summaryrefslogtreecommitdiffstats
path: root/meta-oe
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2023-11-03 17:19:21 -0700
committerKhem Raj <raj.khem@gmail.com>2023-11-06 08:47:16 -0800
commit3259bc75f5cbe83623e340efd4518414ae2f7593 (patch)
treed736749d9ac5e6c71721c544193c3719c2e28c27 /meta-oe
parent686d75a3847a632c45dbaae01a04a74d8f1b423b (diff)
downloadmeta-openembedded-3259bc75f5cbe83623e340efd4518414ae2f7593.tar.gz
libtorrent: upgrade 0.13.8 -> 1
Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'meta-oe')
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch44
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch56
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0003-Add-space-to-fmt-str-in-log_gz_file_write.patch27
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch379
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch47
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch30
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch105
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch24
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch46
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch58
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch60
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch45
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch45
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch27
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch29
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch40
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch22
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch22
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch22
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch74
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch293
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch64
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch123
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch30
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch109
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch101
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch7365
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch26
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch27
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch470
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch33
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch843
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch2710
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch22
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch48
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch135
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch594
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch199
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch32
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch457
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch85
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch444
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch2979
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch29
-rw-r--r--meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb51
45 files changed, 18468 insertions, 3 deletions
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch
new file mode 100644
index 0000000000..bc4bade513
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch
@@ -0,0 +1,44 @@
1From c2b119de0e66fb047bb20e445ac8e25824448858 Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Sun, 30 Jul 2017 20:34:47 +0100
4Subject: [PATCH] Fix compilation issue with gcc v6.x and empty CXXFLAGS (See
5 #10)
6
7---
8 configure.ac | 1 +
9 scripts/rak_compiler.m4 | 13 +++++++++++++
10 2 files changed, 14 insertions(+)
11
12diff --git a/configure.ac b/configure.ac
13index 65e34872..2f29e3f9 100644
14--- a/configure.ac
15+++ b/configure.ac
16@@ -28,6 +28,7 @@ AC_C_BIGENDIAN(
17 AC_MSG_ERROR([Could not determine endianness])
18 )
19
20+RAK_CHECK_CXXFLAGS
21 RAK_ENABLE_DEBUG
22 RAK_ENABLE_EXTRA_DEBUG
23 RAK_ENABLE_WERROR
24diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4
25index 39bd19a7..87871abf 100644
26--- a/scripts/rak_compiler.m4
27+++ b/scripts/rak_compiler.m4
28@@ -1,3 +1,16 @@
29+AC_DEFUN([RAK_CHECK_CXXFLAGS], [
30+
31+ AC_MSG_CHECKING([for user-defined CXXFLAGS])
32+
33+ if test -n "$CXXFLAGS"; then
34+ AC_MSG_RESULT([user-defined "$CXXFLAGS"])
35+ else
36+ CXXFLAGS="-O2"
37+ AC_MSG_RESULT([default "$CXXFLAGS"])
38+ fi
39+])
40+
41+
42 AC_DEFUN([RAK_ENABLE_DEBUG], [
43 AC_ARG_ENABLE(debug,
44 AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch
new file mode 100644
index 0000000000..532b65a7c9
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch
@@ -0,0 +1,56 @@
1From 8229218dff1105e9fb2bb2c7510910a0db98f3ef Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Wed, 2 Aug 2017 12:48:27 +0100
4Subject: [PATCH] Modfiy gcc v6.x fix for empty CXXFLAGS (See #10)
5
6---
7 configure.ac | 1 +
8 scripts/rak_compiler.m4 | 21 +++++++++++++++++----
9 2 files changed, 18 insertions(+), 4 deletions(-)
10
11diff --git a/configure.ac b/configure.ac
12index 2f29e3f9..a6df6b80 100644
13--- a/configure.ac
14+++ b/configure.ac
15@@ -28,6 +28,7 @@ AC_C_BIGENDIAN(
16 AC_MSG_ERROR([Could not determine endianness])
17 )
18
19+RAK_CHECK_CFLAGS
20 RAK_CHECK_CXXFLAGS
21 RAK_ENABLE_DEBUG
22 RAK_ENABLE_EXTRA_DEBUG
23diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4
24index 87871abf..9a361bed 100644
25--- a/scripts/rak_compiler.m4
26+++ b/scripts/rak_compiler.m4
27@@ -1,12 +1,25 @@
28+AC_DEFUN([RAK_CHECK_CFLAGS], [
29+
30+ AC_MSG_CHECKING([for user-defined CFLAGS])
31+
32+ if test "$CFLAGS" = ""; then
33+ unset CFLAGS
34+ AC_MSG_RESULT([undefined])
35+ else
36+ AC_MSG_RESULT([user-defined "$CFLAGS"])
37+ fi
38+])
39+
40+
41 AC_DEFUN([RAK_CHECK_CXXFLAGS], [
42
43 AC_MSG_CHECKING([for user-defined CXXFLAGS])
44
45- if test -n "$CXXFLAGS"; then
46- AC_MSG_RESULT([user-defined "$CXXFLAGS"])
47+ if test "$CXXFLAGS" = ""; then
48+ unset CXXFLAGS
49+ AC_MSG_RESULT([undefined])
50 else
51- CXXFLAGS="-O2"
52- AC_MSG_RESULT([default "$CXXFLAGS"])
53+ AC_MSG_RESULT([user-defined "$CXXFLAGS"])
54 fi
55 ])
56
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0003-Add-space-to-fmt-str-in-log_gz_file_write.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0003-Add-space-to-fmt-str-in-log_gz_file_write.patch
new file mode 100644
index 0000000000..810b4d4ca8
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0003-Add-space-to-fmt-str-in-log_gz_file_write.patch
@@ -0,0 +1,27 @@
1From 48635a0fdb06b8572809dc54c630109db1e6e85c Mon Sep 17 00:00:00 2001
2From: Matt Traudt <sirmatt@ksu.edu>
3Date: Mon, 20 Nov 2017 15:22:51 -0500
4Subject: [PATCH] Add space to fmt str in log_gz_file_write
5
6Without this space, the log level identifier ('D', 'I', etc.)
7would be right next to actual content.
8
9Before: <timestamp> Depoll->pcb(17): Open event.
10After: <timestamp> D epoll->pcb(17): Open event.
11---
12 src/torrent/utils/log.cc | 2 +-
13 1 file changed, 1 insertion(+), 1 deletion(-)
14
15diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
16index 646d36e3..58b563a6 100644
17--- a/src/torrent/utils/log.cc
18+++ b/src/torrent/utils/log.cc
19@@ -381,7 +381,7 @@ log_gz_file_write(std::shared_ptr<log_gz_output>& outfile, const char* data, siz
20
21 // Normal groups are nul-terminated strings.
22 if (group >= 0) {
23- const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c");
24+ const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ");
25
26 int buffer_length = snprintf(buffer, 64, fmt,
27 cachedTime.seconds(),
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch
new file mode 100644
index 0000000000..c7a01409da
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch
@@ -0,0 +1,379 @@
1From facd1b78071e315a2e5ee4992d3545dae4290e07 Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Sun, 10 Dec 2017 18:51:32 +0000
4Subject: [PATCH] IPv4 filter enhancement #11IPv4 filter enhancement (Closes
5 #11)
6
7---
8 src/torrent/peer/peer_list.cc | 23 ++-
9 src/torrent/peer/peer_list.h | 2 +-
10 src/torrent/utils/extents.h | 267 ++++++++++++++--------------------
11 3 files changed, 134 insertions(+), 158 deletions(-)
12
13diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc
14index 23ca651a..aa60939a 100644
15--- a/src/torrent/peer/peer_list.cc
16+++ b/src/torrent/peer/peer_list.cc
17@@ -146,7 +146,11 @@ PeerList::insert_address(const sockaddr* sa, int flags) {
18
19 PeerInfo* peerInfo = new PeerInfo(sa);
20 peerInfo->set_listen_port(address->port());
21- peerInfo->set_flags(m_ipv4_table.at(address->sa_inet()->address_h()) & PeerInfo::mask_ip_table);
22+ uint32_t host_byte_order_ipv4_addr = address->sa_inet()->address_h();
23+
24+ // IPv4 addresses stored in host byte order in ipv4_table so they are comparable. ntohl has been called
25+ if(m_ipv4_table.defined(host_byte_order_ipv4_addr))
26+ peerInfo->set_flags(m_ipv4_table.at(host_byte_order_ipv4_addr) & PeerInfo::mask_ip_table);
27
28 manager->client_list()->retrieve_unknown(&peerInfo->mutable_client_info());
29
30@@ -264,12 +268,25 @@ PeerList::connected(const sockaddr* sa, int flags) {
31 !socket_address_key::is_comparable_sockaddr(sa))
32 return NULL;
33
34- int filter_value = m_ipv4_table.at(address->sa_inet()->address_h());
35+ uint32_t host_byte_order_ipv4_addr = address->sa_inet()->address_h();
36+ int filter_value = 0;
37+
38+ // IPv4 addresses stored in host byte order in ipv4_table so they are comparable. ntohl has been called
39+ if(m_ipv4_table.defined(host_byte_order_ipv4_addr))
40+ filter_value = m_ipv4_table.at(host_byte_order_ipv4_addr);
41
42 // We should also remove any PeerInfo objects already for this
43 // address.
44- if ((filter_value & PeerInfo::flag_unwanted))
45+ if ((filter_value & PeerInfo::flag_unwanted)) {
46+ char ipv4_str[INET_ADDRSTRLEN];
47+ uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr);
48+
49+ inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN);
50+
51+ lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str);
52+
53 return NULL;
54+ }
55
56 PeerInfo* peerInfo;
57 range_type range = base_type::equal_range(sock_key);
58diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h
59index a3b409cb..4c2f707d 100644
60--- a/src/torrent/peer/peer_list.h
61+++ b/src/torrent/peer/peer_list.h
62@@ -46,7 +46,7 @@ namespace torrent {
63
64 class DownloadInfo;
65
66-typedef extents<uint32_t, int, 32, 256, 8> ipv4_table;
67+typedef extents<uint32_t, int> ipv4_table;
68
69 class LIBTORRENT_EXPORT PeerList : private std::multimap<socket_address_key, PeerInfo*> {
70 public:
71diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h
72index 8ec1e600..c2b887b1 100644
73--- a/src/torrent/utils/extents.h
74+++ b/src/torrent/utils/extents.h
75@@ -37,191 +37,150 @@
76 #ifndef LIBTORRENT_UTILS_EXTENTS_H
77 #define LIBTORRENT_UTILS_EXTENTS_H
78
79-#include lt_tr1_array
80
81-#include <algorithm>
82+#include <map>
83+#include <stdexcept>
84
85 namespace torrent {
86
87-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
88-struct extents_base {
89- typedef Key key_type;
90- typedef std::pair<Key, Key> range_type;
91- typedef std::pair<extents_base*, Tp> mapped_type;
92- typedef Tp mapped_value_type;
93-
94- typedef std::array<mapped_type, TableSize> table_type;
95-
96- extents_base(key_type pos, unsigned int mb, mapped_value_type val);
97- extents_base(extents_base* parent, typename table_type::const_iterator itr);
98- ~extents_base();
99-
100- bool is_divisible(key_type key) const { return key % mask_bits == 0; }
101- bool is_leaf_branch() const { return mask_bits == 0; }
102- bool is_equal_range(key_type first, key_type last, const mapped_value_type& val) const;
103-
104- unsigned int sizeof_data() const;
105-
106- typename table_type::iterator partition_at(key_type key) { return table.begin() + ((key >> mask_bits) & (TableSize - 1)); }
107- typename table_type::const_iterator partition_at(key_type key) const { return table.begin() + ((key >> mask_bits) & (TableSize - 1)); }
108-
109- unsigned int mask_distance(unsigned int mb) { return (~(~key_type() << mb) >> mask_bits); }
110-
111- key_type partition_pos(typename table_type::const_iterator part) const { return position + (std::distance(table.begin(), part) << mask_bits); }
112-
113- void insert(key_type pos, unsigned int mb, const mapped_value_type& val);
114-
115- const mapped_value_type& at(key_type key) const;
116-
117- unsigned int mask_bits;
118- key_type position;
119- table_type table;
120-};
121-
122-template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
123-class extents : private extents_base<Key, Tp, TableSize, TableBits> {
124+template <class Address, class Value, class Compare=std::less<Address> >
125+class extents {
126 public:
127- typedef extents_base<Key, Tp, TableSize, TableBits> base_type;
128-
129- typedef typename base_type::key_type key_type;
130- typedef base_type value_type;
131- typedef typename base_type::range_type range_type;
132- typedef typename base_type::mapped_type mapped_type;
133- typedef typename base_type::mapped_value_type mapped_value_type;
134- typedef typename base_type::table_type table_type;
135-
136- static const key_type mask_bits = MaskBits;
137- static const key_type table_bits = TableBits;
138- static const key_type table_size = TableSize;
139-
140- using base_type::at;
141- using base_type::sizeof_data;
142+ typedef Address key_type; // start address
143+ typedef Value mapped_value_type; // The value mapped to the ip range
144+ typedef std::pair<Address, Value> mapped_type; // End address, value mapped to ip range
145+ typedef std::map<key_type, mapped_type, Compare> range_map_type; // The map itself
146
147 extents();
148+ ~extents();
149
150- bool is_equal_range(key_type first, key_type last, const mapped_value_type& val) const;
151-
152- void insert(key_type pos, unsigned int mb, const mapped_value_type& val);
153+ void insert(key_type address_start, key_type address_end, mapped_value_type value);
154+ bool defined(key_type address_start, key_type address_end);
155+ bool defined(key_type address);
156+ key_type get_matching_key(key_type address_start, key_type address_end); // throws error on not defined. test with defined()
157+ mapped_value_type at(key_type address_start, key_type address_end); // throws error on not defined. test with defined()
158+ mapped_value_type at(key_type address); // throws error on not defined. test with defined()
159+ unsigned int sizeof_data() const;
160
161- base_type* data() { return this; }
162+ range_map_type range_map;
163 };
164
165-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
166-extents_base<Key, Tp, TableSize, TableBits>::extents_base(key_type pos, unsigned int mb, mapped_value_type val) :
167- mask_bits(mb), position(pos) {
168- std::fill(table.begin(), table.end(), mapped_type(NULL, mapped_value_type()));
169+///////////////////////////////////////
170+// CONSTRUCTOR [PLACEHOLDER]
171+///////////////////////////////////////
172+template <class Address, class Value, class Compare >
173+extents<Address, Value, Compare>::extents() {
174+ //nothing to do
175+ return;
176 }
177
178-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
179-extents_base<Key, Tp, TableSize, TableBits>::extents_base(extents_base* parent, typename table_type::const_iterator itr) :
180- mask_bits(parent->mask_bits - TableBits), position(parent->partition_pos(itr)) {
181- std::fill(table.begin(), table.end(), mapped_type(NULL, itr->second));
182+///////////////////////////////////////
183+// DESTRUCTOR [PLACEHOLDER]
184+///////////////////////////////////////
185+template <class Address, class Value, class Compare >
186+extents<Address, Value, Compare>::~extents() {
187+ //nothing to do. map destructor can handle cleanup.
188+ return;
189 }
190
191-template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
192-extents<Key, Tp, MaskBits, TableSize, TableBits>::extents() :
193- base_type(key_type(), mask_bits - table_bits, mapped_value_type())
194-{
195-}
196+//////////////////////////////////////////////////////////////////////////////////
197+// INSERT O(log N) assuming no overlapping ranges
198+/////////////////////////////////////////////////////////////////////////////////
199+template <class Address, class Value, class Compare >
200+void extents<Address, Value, Compare>::insert(key_type address_start, key_type address_end, mapped_value_type value) {
201+ //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.
202+ typename range_map_type::iterator iter = range_map.upper_bound(address_start);
203+ if( iter != range_map.begin() ) { iter--; }
204+ bool ignore_due_to_total_overlap = false;
205+ while( iter->first <= address_end && iter != range_map.end() ) {
206+ key_type delete_key = iter->first;
207+ bool do_delete_due_to_overlap = iter->first <= address_end && (iter->second).first >= address_start && (iter->second).second != value;
208+ bool do_delete_due_to_total_overlap = address_start <= iter->first && address_end >= (iter->second).first;
209+ iter++;
210+ if(do_delete_due_to_overlap || do_delete_due_to_total_overlap) {
211+ range_map.erase (delete_key);
212+ }
213+ else {
214+ ignore_due_to_total_overlap = ignore_due_to_total_overlap || ( iter->first <= address_start && (iter->second).first >= address_end );
215+ }
216+ }
217
218-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
219-extents_base<Key, Tp, TableSize, TableBits>::~extents_base() {
220- for (typename table_type::const_iterator itr = table.begin(), last = table.end(); itr != last; itr++)
221- delete itr->first;
222+ if(!ignore_due_to_total_overlap) {
223+ mapped_type entry;
224+ entry.first = address_end;
225+ entry.second = value;
226+ range_map.insert( std::pair<key_type,mapped_type>(address_start, entry) );
227+ }
228 }
229
230-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
231-unsigned int
232-extents_base<Key, Tp, TableSize, TableBits>::sizeof_data() const {
233- unsigned int sum = sizeof(*this);
234-
235- for (typename table_type::const_iterator itr = table.begin(), last = table.end(); itr != last; itr++)
236- if (itr->first != NULL)
237- sum += itr->first->sizeof_data();
238-
239- return sum;
240+//////////////////////////////////////////////////////////////////////
241+// DEFINED O(log N) assuming no overlapping ranges
242+//////////////////////////////////////////////////////////////////////
243+template <class Address, class Value, class Compare >
244+bool extents<Address, Value, Compare>::defined(key_type address_start, key_type address_end) {
245+ bool defined = false;
246+ typename range_map_type::iterator iter = range_map.upper_bound(address_start);
247+ if( iter != range_map.begin() ) { iter--; }
248+ while( iter->first <= address_end && !defined && iter != range_map.end() ) {
249+ defined = iter->first <= address_end && (iter->second).first >= address_start;
250+ iter++;
251+ }
252+ return defined;
253 }
254-
255-template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
256-void
257-extents<Key, Tp, MaskBits, TableSize, TableBits>::insert(key_type pos, unsigned int mb, const mapped_value_type& val) {
258- key_type mask = ~key_type() << mb;
259-
260- base_type::insert(pos & mask, mb, val);
261+template <class Address, class Value, class Compare >
262+bool extents<Address, Value, Compare>::defined(key_type address) {
263+ return defined(address, address);
264 }
265
266-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
267-void
268-extents_base<Key, Tp, TableSize, TableBits>::insert(key_type pos, unsigned int mb, const mapped_value_type& val) {
269- // RESTRICTED
270- typename table_type::iterator first = partition_at(pos);
271- typename table_type::iterator last = partition_at(pos) + mask_distance(mb) + 1;
272-
273- if (mb < mask_bits) {
274- if (first->first == NULL)
275- first->first = new extents_base(this, first);
276+//////////////////////////////////////////////////////////////////////
277+// GET_MATCHING_KEY O(log N) assuming no overlapping ranges
278+//////////////////////////////////////////////////////////////////////
279+template <class Address, class Value, class Compare >
280+typename extents<Address, Value, Compare>::key_type extents<Address, Value, Compare>::get_matching_key(key_type address_start, key_type address_end) {
281+ key_type key;
282+ bool defined = false;
283+ typename range_map_type::iterator iter = range_map.upper_bound(address_start);
284+ if( iter != range_map.begin() ) { iter--; }
285+ while( iter->first <= address_end && !defined && iter != range_map.end() ) {
286+ defined = iter->first <= address_end && (iter->second).first >= address_start;
287+ if(defined)
288+ key = iter->first;
289
290- first->first->insert(pos, mb, val);
291- return;
292+ iter++;
293 }
294-
295- while (first != last) {
296- if (first->first != NULL) {
297- delete first->first;
298- first->first = NULL;
299- }
300-
301- (first++)->second = val;
302+ // this will cause exception to be thrown
303+ if(!defined) {
304+ std::out_of_range e("nothing defined for specified key");
305+ throw e;
306 }
307+ return key;
308 }
309
310-template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
311-bool
312-extents<Key, Tp, MaskBits, TableSize, TableBits>::is_equal_range(key_type first, key_type last, const mapped_value_type& val) const {
313- // RESTRICTED
314- first = std::max(first, key_type());
315- last = std::min(last, key_type() + (~key_type() >> (sizeof(key_type) * 8 - MaskBits)));
316-
317- if (first <= last)
318- return base_type::is_equal_range(first, last, val);
319- else
320- return true;
321+//////////////////////////////////////////////////////////////////////
322+// AT O(log N) assuming no overlapping ranges
323+//////////////////////////////////////////////////////////////////////
324+template <class Address, class Value, class Compare >
325+typename extents<Address, Value, Compare>::mapped_value_type extents<Address, Value, Compare>::at(key_type address_start, key_type address_end) {
326+ key_type key = get_matching_key(address_start, address_end);
327+ mapped_type entry = range_map.at(key);
328+ return entry.second;
329 }
330-
331-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
332-bool
333-extents_base<Key, Tp, TableSize, TableBits>::is_equal_range(key_type key_first, key_type key_last, const mapped_value_type& val) const {
334- // RESTRICTED
335- typename table_type::const_iterator first = partition_at(key_first);
336- typename table_type::const_iterator last = partition_at(key_last) + 1;
337-
338- do {
339- // std::cout << "shift_amount " << key_first << ' ' << key_last << std::endl;
340-
341- if (first->first == NULL && val != first->second)
342- return false;
343-
344- if (first->first != NULL && !first->first->is_equal_range(std::max(key_first, partition_pos(first)),
345- std::min(key_last, partition_pos(first + 1) - 1), val))
346- return false;
347-
348- } while (++first != last);
349-
350- return true;
351+template <class Address, class Value, class Compare >
352+typename extents<Address, Value, Compare>::mapped_value_type extents<Address, Value, Compare>::at(key_type address) {
353+ return at(address, address);
354 }
355
356-// Assumes 'key' is within the range of the range.
357-template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
358-const typename extents_base<Key, Tp, TableSize, TableBits>::mapped_value_type&
359-extents_base<Key, Tp, TableSize, TableBits>::at(key_type key) const {
360- typename table_type::const_iterator itr = partition_at(key);
361-
362- while (itr->first != NULL)
363- itr = itr->first->partition_at(key);
364-
365- return itr->second;
366+//////////////////////////////////////////////////////////////////////
367+// SIZEOF_DATA O(1)
368+//////////////////////////////////////////////////////////////////////
369+template <class Address, class Value, class Compare >
370+unsigned int extents<Address, Value, Compare>::sizeof_data() const {
371+ // we don't know overhead on map, so this won't be accurate. just estimate.
372+ unsigned int entry_size = sizeof(key_type) + sizeof(mapped_type);
373+ return entry_size * range_map.size();
374 }
375
376+
377 }
378
379 #endif
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch
new file mode 100644
index 0000000000..45f92524fc
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch
@@ -0,0 +1,47 @@
1From 4a5ed3897e772c75929b376b08985d844898b619 Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Tue, 12 Dec 2017 15:19:51 +0000
4Subject: [PATCH] Disable extents test to pass TravisCI (See #11)
5
6---
7 test/torrent/utils/test_extents.cc | 10 ++++++----
8 1 file changed, 6 insertions(+), 4 deletions(-)
9
10diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc
11index 6ac5a57d..d6b8d11d 100644
12--- a/test/torrent/utils/test_extents.cc
13+++ b/test/torrent/utils/test_extents.cc
14@@ -16,10 +16,11 @@ void
15 ExtentsTest::tearDown() {
16 }
17
18-typedef torrent::extents<uint32_t, int, 8, 16, 4> extent_type_1;
19+//typedef torrent::extents<uint32_t, int, 8, 16, 4> extent_type_1;
20+typedef torrent::extents<uint32_t, int> extent_type_1;
21
22 // typedef torrent::extents<uint32_t, int, 0, 256, 16> extent_type_3;
23-
24+/*
25 template <typename Extent>
26 bool
27 verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) {
28@@ -46,11 +47,11 @@ static const int val_basic_1[] = {1, 0, 1};
29
30 // static const uint32_t idx_basic_2[] = {0, 1, 16, 255, 256, 256};
31 // static const int val_basic_2[] = {1, 0, 2, 1};
32-
33+*/
34 void
35 ExtentsTest::test_basic() {
36 extent_type_1 extent_1;
37-
38+/*
39 // Test empty.
40 CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty));
41
42@@ -68,4 +69,5 @@ ExtentsTest::test_basic() {
43 // extent_1.insert(38, 3, 2);
44
45 // CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_2, val_basic_2));
46+*/
47 }
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch
new file mode 100644
index 0000000000..645cf0f990
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch
@@ -0,0 +1,30 @@
1From da7db7db29a8488e29d3b0f02906c5db379d4b6d Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Thu, 7 Jun 2018 13:18:03 +0900
4Subject: [PATCH] Bumped version to 0.13.7.
5
6---
7 configure.ac | 8 ++++----
8 1 file changed, 4 insertions(+), 4 deletions(-)
9
10diff --git a/configure.ac b/configure.ac
11index a6df6b80..5b1ea237 100644
12--- a/configure.ac
13+++ b/configure.ac
14@@ -1,12 +1,12 @@
15-AC_INIT(libtorrent, 0.13.6, sundell.software@gmail.com)
16+AC_INIT(libtorrent, 0.13.7, sundell.software@gmail.com)
17
18 LT_INIT([disable-static])
19
20 dnl Find a better way to do this
21-AC_DEFINE(PEER_NAME, "-lt0D60-", Identifier that is part of the default peer id)
22-AC_DEFINE(PEER_VERSION, "lt\x0D\x60", 4 byte client and version identifier for DHT)
23+AC_DEFINE(PEER_NAME, "-lt0D70-", Identifier that is part of the default peer id)
24+AC_DEFINE(PEER_VERSION, "lt\x0D\x70", 4 byte client and version identifier for DHT)
25
26-LIBTORRENT_CURRENT=19
27+LIBTORRENT_CURRENT=20
28 LIBTORRENT_REVISION=0
29 LIBTORRENT_AGE=0
30
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch
new file mode 100644
index 0000000000..eaec545bbb
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch
@@ -0,0 +1,105 @@
1From dbf6abfd6f905b9218465d15eebec7eedaaed6b0 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Tue, 20 Dec 2016 19:51:02 +0900
4Subject: [PATCH] Added support for openssl 1.1.
5
6---
7 configure.ac | 4 ++++
8 src/utils/diffie_hellman.cc | 36 ++++++++++++++++++++++++++++++++++--
9 2 files changed, 38 insertions(+), 2 deletions(-)
10
11diff --git a/configure.ac b/configure.ac
12index 5b1ea237..b885714d 100644
13--- a/configure.ac
14+++ b/configure.ac
15@@ -71,12 +71,15 @@ AC_ARG_ENABLE(openssl,
16 [ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
17 [
18 if test "$enableval" = "yes"; then
19+dnl move to scripts.
20 PKG_CHECK_MODULES(OPENSSL, libcrypto,
21 CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
22 LIBS="$LIBS $OPENSSL_LIBS")
23
24 AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
25 AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
26+ AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
27+
28 else
29 AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
30 fi
31@@ -87,6 +90,7 @@ AC_ARG_ENABLE(openssl,
32
33 AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
34 AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
35+ AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
36 ]
37 )
38
39diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc
40index aa653d45..7ec13165 100644
41--- a/src/utils/diffie_hellman.cc
42+++ b/src/utils/diffie_hellman.cc
43@@ -54,11 +54,23 @@ DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength,
44 m_secret(NULL), m_size(0) {
45
46 #ifdef USE_OPENSSL
47+
48 m_dh = DH_new();
49+
50+#ifdef USE_OPENSSL_1_1
51+ BIGNUM * const dh_p = BN_bin2bn(prime, primeLength, NULL);
52+ BIGNUM * const dh_g = BN_bin2bn(generator, generatorLength, NULL);
53+
54+ if (dh_p == NULL || dh_g == NULL ||
55+ !DH_set0_pqg(m_dh, dh_p, NULL, dh_g))
56+ throw internal_error("Could not generate Diffie-Hellman parameters");
57+#else
58 m_dh->p = BN_bin2bn(prime, primeLength, NULL);
59 m_dh->g = BN_bin2bn(generator, generatorLength, NULL);
60+#endif
61
62 DH_generate_key(m_dh);
63+
64 #else
65 throw internal_error("Compiled without encryption support.");
66 #endif
67@@ -74,7 +86,19 @@ DiffieHellman::~DiffieHellman() {
68 bool
69 DiffieHellman::is_valid() const {
70 #ifdef USE_OPENSSL
71+ if (m_dh == NULL)
72+ return false;
73+
74+#ifdef USE_OPENSSL_1_1
75+ const BIGNUM *pub_key;
76+
77+ DH_get0_key(m_dh, &pub_key, NULL);
78+
79+ return pub_key != NULL;
80+#else
81 return m_dh != NULL && m_dh->pub_key != NULL;
82+#endif
83+
84 #else
85 return false;
86 #endif
87@@ -103,8 +127,16 @@ DiffieHellman::store_pub_key(unsigned char* dest, unsigned int length) {
88 #ifdef USE_OPENSSL
89 std::memset(dest, 0, length);
90
91- if ((int)length >= BN_num_bytes(m_dh->pub_key))
92- BN_bn2bin(m_dh->pub_key, dest + length - BN_num_bytes(m_dh->pub_key));
93+ const BIGNUM *pub_key;
94+
95+#ifdef USE_OPENSSL_1_1
96+ DH_get0_key(m_dh, &pub_key, NULL);
97+#else
98+ pub_key = m_dh->pub_key;
99+#endif
100+
101+ if ((int)length >= BN_num_bytes(pub_key))
102+ BN_bn2bin(pub_key, dest + length - BN_num_bytes(pub_key));
103 #endif
104 }
105
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch
new file mode 100644
index 0000000000..6625fb55cc
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch
@@ -0,0 +1,24 @@
1From c2ec5e0fb8ce7a0df513b5f4086e23d92049ef0e Mon Sep 17 00:00:00 2001
2From: Stephen Shkardoon <ss23@ss23.geek.nz>
3Date: Mon, 25 Jun 2018 20:05:18 +1200
4Subject: [PATCH] Use AC_COMPILE instead of AC_RUN to check for execinfo.h
5
6This way enables cross compiling, since we don't need to run anything
7during the configure script.
8---
9 scripts/common.m4 | 2 +-
10 1 file changed, 1 insertion(+), 1 deletion(-)
11
12diff --git a/scripts/common.m4 b/scripts/common.m4
13index ff023928..b6d051f5 100644
14--- a/scripts/common.m4
15+++ b/scripts/common.m4
16@@ -153,7 +153,7 @@ dnl Need to fix this so that it uses the stuff defined by the system.
17 AC_DEFUN([TORRENT_CHECK_EXECINFO], [
18 AC_MSG_CHECKING(for execinfo.h)
19
20- AC_RUN_IFELSE([AC_LANG_SOURCE([
21+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
22 #include <execinfo.h>
23 int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
24 ])],
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch
new file mode 100644
index 0000000000..974f992def
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch
@@ -0,0 +1,46 @@
1From b0fb874a8921fa4ba2ea0923d779fae8f70c82b1 Mon Sep 17 00:00:00 2001
2From: Stephen Shkardoon <ss23@ss23.geek.nz>
3Date: Thu, 21 Jun 2018 14:38:30 +1200
4Subject: [PATCH] Modify configure to prevent unnecessary kqueue checks
5
6By only running the TORRENT_CHECK_KQUEUE_SOCKET_ONLY check if kqueue support
7is already detected, we increase the number of platforms that we can
8cross compile on.
9Otherwise, the cross compilation fails due to TORRENT_CHECK_KQUEUE_SOCKET_ONLY
10using AC_RUN_IFELSE, which fails during cross compilation.
11---
12 scripts/checks.m4 | 4 +---
13 1 file changed, 1 insertion(+), 3 deletions(-)
14
15diff --git a/scripts/checks.m4 b/scripts/checks.m4
16index 8d77fc5e..c9333561 100644
17--- a/scripts/checks.m4
18+++ b/scripts/checks.m4
19@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
20 [
21 AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
22 AC_MSG_RESULT(yes)
23+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
24 ], [
25 AC_MSG_RESULT(no)
26 ])
27@@ -137,7 +138,6 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
28 [
29 if test "$withval" = "yes"; then
30 TORRENT_CHECK_KQUEUE
31- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
32 fi
33 ])
34 ])
35@@ -149,11 +149,9 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
36 [
37 if test "$withval" = "yes"; then
38 TORRENT_CHECK_KQUEUE
39- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
40 fi
41 ], [
42 TORRENT_CHECK_KQUEUE
43- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
44 ])
45 ])
46
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch
new file mode 100644
index 0000000000..562cdae7a5
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch
@@ -0,0 +1,58 @@
1From 4ff83fc53b2c7462b02f804ee20414d85944e3c9 Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Sun, 14 May 2017 19:36:09 +0100
4Subject: [PATCH] Display info on failed tracker bencode parsing (See #9)
5
6---
7 rak/string_manip.h | 20 ++++++++++++++++++++
8 src/tracker/tracker_http.cc | 6 ++++--
9 2 files changed, 24 insertions(+), 2 deletions(-)
10
11diff --git a/rak/string_manip.h b/rak/string_manip.h
12index f8d3f590..68614d2a 100644
13--- a/rak/string_manip.h
14+++ b/rak/string_manip.h
15@@ -371,6 +371,26 @@ is_all_name(const Sequence& src) {
16 return is_all_name(src.begin(), src.end());
17 }
18
19+template <typename Iterator>
20+std::string
21+sanitize(Iterator first, Iterator last) {
22+ std::string dest;
23+ for (; first != last; ++first) {
24+ if (std::isprint(*first) && *first != '\r' && *first != '\n' && *first != '\t')
25+ dest += *first;
26+ else
27+ dest += " ";
28+ }
29+
30+ return dest;
31+}
32+
33+template <typename Sequence>
34+std::string
35+sanitize(const Sequence& src) {
36+ return trim(sanitize(src.begin(), src.end()));
37+}
38+
39 }
40
41 #endif
42diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
43index 553f922c..b6d9e0ac 100644
44--- a/src/tracker/tracker_http.cc
45+++ b/src/tracker/tracker_http.cc
46@@ -288,8 +288,10 @@ TrackerHttp::receive_done() {
47 Object b;
48 *m_data >> b;
49
50- if (m_data->fail())
51- return receive_failed("Could not parse bencoded data");
52+ if (m_data->fail()) {
53+ std::string dump = m_data->str();
54+ return receive_failed("Could not parse bencoded data: " + rak::sanitize(dump).substr(0,99));
55+ }
56
57 if (!b.is_map())
58 return receive_failed("Root not a bencoded map");
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch
new file mode 100644
index 0000000000..7a8c9aa5ae
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch
@@ -0,0 +1,60 @@
1From 2f197be69057f793d29272b90300f74d0b588d51 Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Mon, 15 May 2017 19:24:33 +0100
4Subject: [PATCH] Strip tags also when displaying info on failed tracker
5 bencode parsing (See #9)
6
7---
8 rak/string_manip.h | 25 +++++++++++++++++++++++++
9 src/tracker/tracker_http.cc | 2 +-
10 2 files changed, 26 insertions(+), 1 deletion(-)
11
12diff --git a/rak/string_manip.h b/rak/string_manip.h
13index 68614d2a..ae867c98 100644
14--- a/rak/string_manip.h
15+++ b/rak/string_manip.h
16@@ -391,6 +391,31 @@ sanitize(const Sequence& src) {
17 return trim(sanitize(src.begin(), src.end()));
18 }
19
20+template <typename Iterator>
21+std::string striptags(Iterator first, Iterator last) {
22+ bool copychar = true;
23+ std::string dest;
24+
25+ for (; first != last; ++first) {
26+ if (std::isprint(*first) && *first == '<') {
27+ copychar = false;
28+ } else if (std::isprint(*first) && *first == '>') {
29+ copychar = true;
30+ continue;
31+ }
32+
33+ if (copychar)
34+ dest += *first;
35+ }
36+
37+ return dest;
38+}
39+
40+template <typename Sequence>
41+std::string striptags(const Sequence& src) {
42+ return striptags(src.begin(), src.end());
43+}
44+
45 }
46
47 #endif
48diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
49index b6d9e0ac..eefe5a17 100644
50--- a/src/tracker/tracker_http.cc
51+++ b/src/tracker/tracker_http.cc
52@@ -290,7 +290,7 @@ TrackerHttp::receive_done() {
53
54 if (m_data->fail()) {
55 std::string dump = m_data->str();
56- return receive_failed("Could not parse bencoded data: " + rak::sanitize(dump).substr(0,99));
57+ return receive_failed("Could not parse bencoded data: " + rak::sanitize(rak::striptags(dump)).substr(0,99));
58 }
59
60 if (!b.is_map())
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch
new file mode 100644
index 0000000000..f4776247de
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch
@@ -0,0 +1,45 @@
1From 0e86289a8bb5672781e508683bb28aebf9995127 Mon Sep 17 00:00:00 2001
2From: lps-rocks <admin@lps.rocks>
3Date: Mon, 4 Mar 2019 05:03:47 -0500
4Subject: [PATCH] Switch to C++11 MRT RNG for random bytes
5
6Switching 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.
7---
8 rak/string_manip.h | 12 +++++++++---
9 1 file changed, 9 insertions(+), 3 deletions(-)
10
11diff --git a/rak/string_manip.h b/rak/string_manip.h
12index ae867c98..1a09c377 100644
13--- a/rak/string_manip.h
14+++ b/rak/string_manip.h
15@@ -39,9 +39,13 @@
16
17 #include <algorithm>
18 #include <cctype>
19+#include <climits>
20 #include <cstdlib>
21+#include <functional>
22 #include <iterator>
23 #include <locale>
24+#include <random>
25+
26
27 namespace rak {
28
29@@ -312,11 +316,13 @@ transform_hex_str(const Sequence& seq) {
30 template <typename Sequence>
31 Sequence
32 generate_random(size_t length) {
33+ std::random_device rd;
34+ std::mt19937 mt(rd());
35+ using bytes_randomizer = std::independent_bits_engine<std::mt19937, CHAR_BIT, uint8_t>;
36+ bytes_randomizer bytes(mt);
37 Sequence s;
38 s.reserve(length);
39-
40- std::generate_n(std::back_inserter(s), length, &::random);
41-
42+ std::generate_n(std::back_inserter(s), length, std::ref(bytes));
43 return s;
44 }
45
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch
new file mode 100644
index 0000000000..1d4cc3e331
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch
@@ -0,0 +1,45 @@
1From bf35c5f3d4e458a671fdc3c382f4fa06ecaeb119 Mon Sep 17 00:00:00 2001
2From: Vladyslav Movchan <vladislav.movchan@gmail.com>
3Date: Sat, 3 Nov 2018 19:52:56 +0200
4Subject: [PATCH] Prevent loss of 'm_ipv6_socket' attribute which led to
5 execution of setsockopt(..., IPPROTO_IP, IP_TOS, ...) on IPv6 socket
6
7---
8 src/net/socket_fd.cc | 4 ++--
9 src/net/socket_fd.h | 1 +
10 2 files changed, 3 insertions(+), 2 deletions(-)
11
12diff --git a/src/net/socket_fd.cc b/src/net/socket_fd.cc
13index 54cb6ded..f04059f6 100644
14--- a/src/net/socket_fd.cc
15+++ b/src/net/socket_fd.cc
16@@ -251,7 +251,7 @@ SocketFd::accept(rak::socket_address* sa) {
17 socklen_t len = sizeof(rak::socket_address);
18
19 if (sa == NULL) {
20- return SocketFd(::accept(m_fd, NULL, &len));
21+ return SocketFd(::accept(m_fd, NULL, &len), m_ipv6_socket);
22 }
23
24 int fd = ::accept(m_fd, sa->c_sockaddr(), &len);
25@@ -260,7 +260,7 @@ SocketFd::accept(rak::socket_address* sa) {
26 *sa = sa->sa_inet6()->normalize_address();
27 }
28
29- return SocketFd(fd);
30+ return SocketFd(fd, m_ipv6_socket);
31 }
32
33 // unsigned int
34diff --git a/src/net/socket_fd.h b/src/net/socket_fd.h
35index ca765e88..2329b4e9 100644
36--- a/src/net/socket_fd.h
37+++ b/src/net/socket_fd.h
38@@ -51,6 +51,7 @@ public:
39
40 SocketFd() : m_fd(-1) {}
41 explicit SocketFd(int fd) : m_fd(fd) {}
42+ SocketFd(int fd, bool ipv6_socket) : m_fd(fd), m_ipv6_socket(ipv6_socket) {}
43
44 bool is_valid() const { return m_fd >= 0; }
45
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch
new file mode 100644
index 0000000000..4bb1ed21c4
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch
@@ -0,0 +1,27 @@
1From 1890bde5c051d932d1b2940e815d0c82964c474c Mon Sep 17 00:00:00 2001
2From: Gleb Smirnoff <glebius@FreeBSD.org>
3Date: Tue, 2 Oct 2018 18:57:43 -0700
4Subject: [PATCH] If during socket creation AF_INET6 failes initialize sockaddr
5 as AF_INET. Otherwise any bind(2) would fail due to sockaddr address family
6 not matching socket address family.
7
8---
9 src/net/listen.cc | 5 ++++-
10 1 file changed, 4 insertions(+), 1 deletion(-)
11
12diff --git a/src/net/listen.cc b/src/net/listen.cc
13index da1c2e84..d424e94c 100644
14--- a/src/net/listen.cc
15+++ b/src/net/listen.cc
16@@ -75,7 +75,10 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre
17
18 // TODO: Temporary until we refactor:
19 if (bindAddress->family() == 0) {
20- sa.sa_inet6()->clear();
21+ if (m_ipv6_socket)
22+ sa.sa_inet6()->clear();
23+ else
24+ sa.sa_inet()->clear();
25 } else {
26 sa.copy(*bindAddress, bindAddress->length());
27 }
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch
new file mode 100644
index 0000000000..a33a0103b9
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch
@@ -0,0 +1,29 @@
1From cbd946b6cad8c93b3d39ab4f338b3640f684cbfc Mon Sep 17 00:00:00 2001
2From: Adam Fontenot <adam.m.fontenot@gmail.com>
3Date: Sat, 7 Jul 2018 16:52:07 -0700
4Subject: [PATCH] Fixes https://github.com/rakshasa/rtorrent/issues/731
5
6---
7 src/tracker/tracker_http.cc | 4 ++--
8 1 file changed, 2 insertions(+), 2 deletions(-)
9
10diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
11index eefe5a17..1bf94107 100644
12--- a/src/tracker/tracker_http.cc
13+++ b/src/tracker/tracker_http.cc
14@@ -145,13 +145,13 @@ TrackerHttp::send_state(int state) {
15 if (!localAddress->is_address_any())
16 s << "&ip=" << localAddress->address_str();
17
18- if (localAddress->is_address_any() || localAddress->family() != rak::socket_address::pf_inet6) {
19+ if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) {
20 rak::socket_address local_v6;
21 if (get_local_address(rak::socket_address::af_inet6, &local_v6))
22 s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str());
23 }
24
25- if (localAddress->is_address_any() || localAddress->family() != rak::socket_address::pf_inet) {
26+ if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) {
27 rak::socket_address local_v4;
28 if (get_local_address(rak::socket_address::af_inet, &local_v4))
29 s << "&ipv4=" << local_v4.address_str();
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch
new file mode 100644
index 0000000000..6ef5f1ad4d
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch
@@ -0,0 +1,40 @@
1From d49316117401cff4045b1d1194cec60909e45555 Mon Sep 17 00:00:00 2001
2From: chros <chros@chrosGX620>
3Date: Sun, 13 May 2018 11:34:33 +0100
4Subject: [PATCH] Fix honoring throttle.min_peers* settings in rtorrent (See
5 #13)
6
7---
8 src/download/download_main.cc | 17 ++++++-----------
9 1 file changed, 6 insertions(+), 11 deletions(-)
10
11diff --git a/src/download/download_main.cc b/src/download/download_main.cc
12index 48222c38..efe91d66 100644
13--- a/src/download/download_main.cc
14+++ b/src/download/download_main.cc
15@@ -355,19 +355,14 @@ DownloadMain::receive_tracker_success() {
16
17 void
18 DownloadMain::receive_tracker_request() {
19- bool should_stop = false;
20- bool should_start = false;
21+ if (info()->is_pex_enabled() && info()->size_pex() > 0
22+ || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) {
23
24- if (info()->is_pex_enabled() && info()->size_pex() > 0)
25- should_stop = true;
26-
27- if (connection_list()->size() + peer_list()->available_list()->size() / 2 < connection_list()->min_size())
28- should_start = true;
29-
30- if (should_stop)
31 m_tracker_controller->stop_requesting();
32- else if (should_start)
33- m_tracker_controller->start_requesting();
34+ return;
35+ }
36+
37+ m_tracker_controller->start_requesting();
38 }
39
40 struct SocketAddressCompact_less {
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch
new file mode 100644
index 0000000000..7108507a14
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch
@@ -0,0 +1,22 @@
1From 9fd2f35f86397b9259e0c9b7c54444c0ec3c8965 Mon Sep 17 00:00:00 2001
2From: adam <adam@shinka.sh>
3Date: Mon, 26 Feb 2018 16:04:34 +0200
4Subject: [PATCH] increase piece length max
5
6---
7 src/download/download_constructor.cc | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10diff --git a/src/download/download_constructor.cc b/src/download/download_constructor.cc
11index 1bb261bd..67ef4276 100644
12--- a/src/download/download_constructor.cc
13+++ b/src/download/download_constructor.cc
14@@ -157,7 +157,7 @@ DownloadConstructor::parse_info(const Object& b) {
15 } else {
16 chunkSize = b.get_key_value("piece length");
17
18- if (chunkSize <= (1 << 10) || chunkSize > (128 << 20))
19+ if (chunkSize <= (1 << 10) || chunkSize > (128 << 22))
20 throw input_error("Torrent has an invalid \"piece length\".");
21 }
22
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch
new file mode 100644
index 0000000000..f864d23c31
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch
@@ -0,0 +1,22 @@
1From b263b347f14b9d0ca54d04ca92367a98d791dc17 Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Sun, 9 Jun 2019 14:53:32 +0900
4Subject: [PATCH] Set max piece size 512mb.
5
6---
7 src/download/download_constructor.cc | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10diff --git a/src/download/download_constructor.cc b/src/download/download_constructor.cc
11index 67ef4276..1bf362fa 100644
12--- a/src/download/download_constructor.cc
13+++ b/src/download/download_constructor.cc
14@@ -157,7 +157,7 @@ DownloadConstructor::parse_info(const Object& b) {
15 } else {
16 chunkSize = b.get_key_value("piece length");
17
18- if (chunkSize <= (1 << 10) || chunkSize > (128 << 22))
19+ if (chunkSize <= (1 << 10) || chunkSize > (512 << 20))
20 throw input_error("Torrent has an invalid \"piece length\".");
21 }
22
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch
new file mode 100644
index 0000000000..0a06a26883
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch
@@ -0,0 +1,22 @@
1From cdfb4381bedb278dabb8ca75c10858d16b895355 Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Sun, 9 Jun 2019 14:55:44 +0900
4Subject: [PATCH] Fixed compiler warning.
5
6---
7 src/download/download_main.cc | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10diff --git a/src/download/download_main.cc b/src/download/download_main.cc
11index efe91d66..9a3f9df2 100644
12--- a/src/download/download_main.cc
13+++ b/src/download/download_main.cc
14@@ -355,7 +355,7 @@ DownloadMain::receive_tracker_success() {
15
16 void
17 DownloadMain::receive_tracker_request() {
18- if (info()->is_pex_enabled() && info()->size_pex() > 0
19+ if ((info()->is_pex_enabled() && info()->size_pex()) > 0
20 || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) {
21
22 m_tracker_controller->stop_requesting();
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch
new file mode 100644
index 0000000000..0f183816cf
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch
@@ -0,0 +1,74 @@
1From 8934703edb5982661483eb8a29d76e6a726b5fe2 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Mon, 8 Jul 2019 19:37:06 +0200
4Subject: [PATCH] Added _GNU_SOURCE to fallocate test. (neheb)
5
6---
7 scripts/checks.m4 | 10 ++++++----
8 src/data/socket_file.cc | 1 +
9 2 files changed, 7 insertions(+), 4 deletions(-)
10
11diff --git a/scripts/checks.m4 b/scripts/checks.m4
12index c9333561..83be8461 100644
13--- a/scripts/checks.m4
14+++ b/scripts/checks.m4
15@@ -88,7 +88,6 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
16 [
17 AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
18 AC_MSG_RESULT(yes)
19- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
20 ], [
21 AC_MSG_RESULT(no)
22 ])
23@@ -97,7 +96,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
24 AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
25 AC_MSG_CHECKING(whether kqueue supports pipes and ptys)
26
27- AC_RUN_IFELSE([AC_LANG_SOURCE([
28+ AC_LINK_IFELSE([AC_LANG_SOURCE([
29 #include <fcntl.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32@@ -138,6 +137,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
33 [
34 if test "$withval" = "yes"; then
35 TORRENT_CHECK_KQUEUE
36+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
37 fi
38 ])
39 ])
40@@ -149,9 +149,11 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
41 [
42 if test "$withval" = "yes"; then
43 TORRENT_CHECK_KQUEUE
44+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
45 fi
46 ], [
47 TORRENT_CHECK_KQUEUE
48+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
49 ])
50 ])
51
52@@ -172,8 +174,8 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
53 AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
54 AC_MSG_CHECKING(for fallocate)
55
56- AC_TRY_LINK([#include <fcntl.h>
57- #include <linux/falloc.h>
58+ AC_TRY_LINK([#define _GNU_SOURCE
59+ #include <fcntl.h>
60 ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
61 ],
62 [
63diff --git a/src/data/socket_file.cc b/src/data/socket_file.cc
64index 4b4519ed..b359ef8e 100644
65--- a/src/data/socket_file.cc
66+++ b/src/data/socket_file.cc
67@@ -48,6 +48,7 @@
68 #include <sys/types.h>
69
70 #ifdef HAVE_FALLOCATE
71+#define _GNU_SOURCE
72 #include <linux/falloc.h>
73 #endif
74
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch
new file mode 100644
index 0000000000..ad9e45758c
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch
@@ -0,0 +1,293 @@
1From 856d42e2ca3c9810bf84a8bce219000e822540fa Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Fri, 12 Jul 2019 00:29:35 +0200
4Subject: [PATCH] Fixed diffie hellman implementation.
5
6---
7 src/utils/diffie_hellman.cc | 137 ++++++++++++------------------------
8 src/utils/diffie_hellman.h | 67 ++++--------------
9 2 files changed, 59 insertions(+), 145 deletions(-)
10
11diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc
12index 7ec13165..d53a857b 100644
13--- a/src/utils/diffie_hellman.cc
14+++ b/src/utils/diffie_hellman.cc
15@@ -1,118 +1,79 @@
16-// libTorrent - BitTorrent library
17-// Copyright (C) 2005-2011, Jari Sundell
18-//
19-// This program is free software; you can redistribute it and/or modify
20-// it under the terms of the GNU General Public License as published by
21-// the Free Software Foundation; either version 2 of the License, or
22-// (at your option) any later version.
23-//
24-// This program is distributed in the hope that it will be useful,
25-// but WITHOUT ANY WARRANTY; without even the implied warranty of
26-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27-// GNU General Public License for more details.
28-//
29-// You should have received a copy of the GNU General Public License
30-// along with this program; if not, write to the Free Software
31-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32-//
33-// In addition, as a special exception, the copyright holders give
34-// permission to link the code of portions of this program with the
35-// OpenSSL library under certain conditions as described in each
36-// individual source file, and distribute linked combinations
37-// including the two.
38-//
39-// You must obey the GNU General Public License in all respects for
40-// all of the code used other than OpenSSL. If you modify file(s)
41-// with this exception, you may extend this exception to your version
42-// of the file(s), but you are not obligated to do so. If you do not
43-// wish to do so, delete this exception statement from your version.
44-// If you delete this exception statement from all source files in the
45-// program, then also delete it here.
46-//
47-// Contact: Jari Sundell <jaris@ifi.uio.no>
48-//
49-// Skomakerveien 33
50-// 3185 Skoppum, NORWAY
51-
52 #include "config.h"
53
54+#include "diffie_hellman.h"
55+
56+#include "torrent/exceptions.h"
57+
58 #include <cstring>
59-#include <string>
60
61 #ifdef USE_OPENSSL
62+#include <openssl/dh.h>
63 #include <openssl/bn.h>
64 #endif
65
66-#include "diffie_hellman.h"
67-#include "torrent/exceptions.h"
68-
69 namespace torrent {
70
71-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
72-DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength,
73- const unsigned char *generator, int generatorLength) :
74- m_secret(NULL), m_size(0) {
75-
76 #ifdef USE_OPENSSL
77
78- m_dh = DH_new();
79-
80-#ifdef USE_OPENSSL_1_1
81- BIGNUM * const dh_p = BN_bin2bn(prime, primeLength, NULL);
82- BIGNUM * const dh_g = BN_bin2bn(generator, generatorLength, NULL);
83+static void dh_free(void* dh) { DH_free(reinterpret_cast<DH*>(dh)); }
84+static DiffieHellman::dh_ptr dh_new() { return DiffieHellman::dh_ptr(reinterpret_cast<void*>(DH_new()), &dh_free); }
85+static DH* dh_get(DiffieHellman::dh_ptr& dh) { return reinterpret_cast<DH*>(dh.get()); }
86
87- if (dh_p == NULL || dh_g == NULL ||
88- !DH_set0_pqg(m_dh, dh_p, NULL, dh_g))
89- throw internal_error("Could not generate Diffie-Hellman parameters");
90+static bool
91+dh_set_pg(DiffieHellman::dh_ptr& dh, BIGNUM* dh_p, BIGNUM* dh_g) {
92+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
93+ return DH_set0_pqg(reinterpret_cast<DH*>(dh.get()), dh_p, nullptr, dh_g);
94 #else
95- m_dh->p = BN_bin2bn(prime, primeLength, NULL);
96- m_dh->g = BN_bin2bn(generator, generatorLength, NULL);
97+ reinterpret_cast<DH*>(dh.get())->p = dh_p;
98+ reinterpret_cast<DH*>(dh.get())->g = dh_g;
99+ return true;
100 #endif
101+}
102
103- DH_generate_key(m_dh);
104-
105+static const BIGNUM* dh_get_pub_key(const DiffieHellman::dh_ptr& dh) {
106+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
107+ const BIGNUM *pub_key;
108+ DH_get0_key(reinterpret_cast<DH*>(dh.get()), &pub_key, nullptr);
109+ return pub_key;
110 #else
111- throw internal_error("Compiled without encryption support.");
112+ return dh != nullptr ? reinterpret_cast<DH*>(dh.get())->pub_key : nullptr;
113 #endif
114-};
115+}
116
117-DiffieHellman::~DiffieHellman() {
118- delete [] m_secret;
119-#ifdef USE_OPENSSL
120- DH_free(m_dh);
121+#else
122+static DiffieHellman::dh_ptr dh_new() { throw internal_error("Compiled without encryption support."); }
123+static void dh_free(void* dh) {}
124+static void* dh_get_pub_key(const DiffieHellman::dh_ptr& dh) { return nullptr; }
125 #endif
126-};
127
128-bool
129-DiffieHellman::is_valid() const {
130-#ifdef USE_OPENSSL
131- if (m_dh == NULL)
132- return false;
133+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
134+DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength,
135+ const unsigned char *generator, int generatorLength) :
136+ m_dh(dh_new()), m_size(0) {
137
138-#ifdef USE_OPENSSL_1_1
139- const BIGNUM *pub_key;
140+#ifdef USE_OPENSSL
141+ BIGNUM* dh_p = BN_bin2bn(prime, primeLength, nullptr);
142+ BIGNUM* dh_g = BN_bin2bn(generator, generatorLength, nullptr);
143
144- DH_get0_key(m_dh, &pub_key, NULL);
145+ if (dh_p == nullptr || dh_g == nullptr || !dh_set_pg(m_dh, dh_p, dh_g))
146+ throw internal_error("Could not generate Diffie-Hellman parameters");
147
148- return pub_key != NULL;
149-#else
150- return m_dh != NULL && m_dh->pub_key != NULL;
151+ DH_generate_key(dh_get(m_dh));
152 #endif
153+};
154
155-#else
156- return false;
157-#endif
158+bool
159+DiffieHellman::is_valid() const {
160+ return dh_get_pub_key(m_dh) != nullptr;
161 }
162
163 bool
164 DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length) {
165 #ifdef USE_OPENSSL
166- BIGNUM* k = BN_bin2bn(pubkey, length, NULL);
167+ BIGNUM* k = BN_bin2bn(pubkey, length, nullptr);
168
169- delete [] m_secret;
170- m_secret = new char[DH_size(m_dh)];
171-
172- m_size = DH_compute_key((unsigned char*)m_secret, k, m_dh);
173+ m_secret.reset(new char[DH_size(dh_get(m_dh))]);
174+ m_size = DH_compute_key(reinterpret_cast<unsigned char*>(m_secret.get()), k, dh_get(m_dh));
175
176 BN_free(k);
177
178@@ -124,16 +85,10 @@ DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length)
179
180 void
181 DiffieHellman::store_pub_key(unsigned char* dest, unsigned int length) {
182-#ifdef USE_OPENSSL
183 std::memset(dest, 0, length);
184
185- const BIGNUM *pub_key;
186-
187-#ifdef USE_OPENSSL_1_1
188- DH_get0_key(m_dh, &pub_key, NULL);
189-#else
190- pub_key = m_dh->pub_key;
191-#endif
192+#ifdef USE_OPENSSL
193+ const BIGNUM *pub_key = dh_get_pub_key(m_dh);
194
195 if ((int)length >= BN_num_bytes(pub_key))
196 BN_bn2bin(pub_key, dest + length - BN_num_bytes(pub_key));
197diff --git a/src/utils/diffie_hellman.h b/src/utils/diffie_hellman.h
198index 432542be..2cec5bee 100644
199--- a/src/utils/diffie_hellman.h
200+++ b/src/utils/diffie_hellman.h
201@@ -1,79 +1,38 @@
202-// libTorrent - BitTorrent library
203-// Copyright (C) 2005-2011, Jari Sundell
204-//
205-// This program is free software; you can redistribute it and/or modify
206-// it under the terms of the GNU General Public License as published by
207-// the Free Software Foundation; either version 2 of the License, or
208-// (at your option) any later version.
209-//
210-// This program is distributed in the hope that it will be useful,
211-// but WITHOUT ANY WARRANTY; without even the implied warranty of
212-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
213-// GNU General Public License for more details.
214-//
215-// You should have received a copy of the GNU General Public License
216-// along with this program; if not, write to the Free Software
217-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
218-//
219-// In addition, as a special exception, the copyright holders give
220-// permission to link the code of portions of this program with the
221-// OpenSSL library under certain conditions as described in each
222-// individual source file, and distribute linked combinations
223-// including the two.
224-//
225-// You must obey the GNU General Public License in all respects for
226-// all of the code used other than OpenSSL. If you modify file(s)
227-// with this exception, you may extend this exception to your version
228-// of the file(s), but you are not obligated to do so. If you do not
229-// wish to do so, delete this exception statement from your version.
230-// If you delete this exception statement from all source files in the
231-// program, then also delete it here.
232-//
233-// Contact: Jari Sundell <jaris@ifi.uio.no>
234-//
235-// Skomakerveien 33
236-// 3185 Skoppum, NORWAY
237-
238 #ifndef LIBTORRENT_DIFFIE_HELLMAN_H
239 #define LIBTORRENT_DIFFIE_HELLMAN_H
240
241 #include "config.h"
242
243+#include <memory>
244 #include <string>
245
246-#ifdef USE_OPENSSL
247-#include <openssl/dh.h>
248-#endif
249-
250 namespace torrent {
251
252 class DiffieHellman {
253 public:
254+ typedef std::unique_ptr<char[]> secret_ptr;
255+ typedef std::unique_ptr<void, void (*)(void*)> dh_ptr;
256+
257 DiffieHellman(const unsigned char prime[], int primeLength,
258 const unsigned char generator[], int generatorLength);
259- ~DiffieHellman();
260
261- bool compute_secret(const unsigned char pubkey[], unsigned int length);
262- void store_pub_key(unsigned char* dest, unsigned int length);
263+ bool is_valid() const;
264
265- bool is_valid() const;
266+ bool compute_secret(const unsigned char pubkey[], unsigned int length);
267+ void store_pub_key(unsigned char* dest, unsigned int length);
268
269- unsigned int size() const { return m_size; }
270+ unsigned int size() const { return m_size; }
271
272- const char* c_str() const { return m_secret; }
273- std::string secret_str() const { return std::string(m_secret, m_size); }
274+ const char* c_str() const { return m_secret.get(); }
275+ std::string secret_str() const { return std::string(m_secret.get(), m_size); }
276
277 private:
278 DiffieHellman(const DiffieHellman& dh);
279 DiffieHellman& operator = (const DiffieHellman& dh);
280
281-#ifdef USE_OPENSSL
282- DH* m_dh;
283-#else
284- void* m_void;
285-#endif
286- char* m_secret;
287- unsigned int m_size;
288+ dh_ptr m_dh;
289+ secret_ptr m_secret;
290+ int m_size;
291 };
292
293 };
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch
new file mode 100644
index 0000000000..66f43f0ce5
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch
@@ -0,0 +1,64 @@
1From 660bbc17e32c518c2727607ee5b73039c7109207 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Sat, 13 Jul 2019 00:07:43 +0200
4Subject: [PATCH] Increased max timeout for tracker requests.
5
6---
7 src/torrent/tracker.h | 40 ++--------------------------------------
8 1 file changed, 2 insertions(+), 38 deletions(-)
9
10diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h
11index 2b00ad47..a528ef6a 100644
12--- a/src/torrent/tracker.h
13+++ b/src/torrent/tracker.h
14@@ -1,39 +1,3 @@
15-// libTorrent - BitTorrent library
16-// Copyright (C) 2005-2011, Jari Sundell
17-//
18-// This program is free software; you can redistribute it and/or modify
19-// it under the terms of the GNU General Public License as published by
20-// the Free Software Foundation; either version 2 of the License, or
21-// (at your option) any later version.
22-//
23-// This program is distributed in the hope that it will be useful,
24-// but WITHOUT ANY WARRANTY; without even the implied warranty of
25-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26-// GNU General Public License for more details.
27-//
28-// You should have received a copy of the GNU General Public License
29-// along with this program; if not, write to the Free Software
30-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31-//
32-// In addition, as a special exception, the copyright holders give
33-// permission to link the code of portions of this program with the
34-// OpenSSL library under certain conditions as described in each
35-// individual source file, and distribute linked combinations
36-// including the two.
37-//
38-// You must obey the GNU General Public License in all respects for
39-// all of the code used other than OpenSSL. If you modify file(s)
40-// with this exception, you may extend this exception to your version
41-// of the file(s), but you are not obligated to do so. If you do not
42-// wish to do so, delete this exception statement from your version.
43-// If you delete this exception statement from all source files in the
44-// program, then also delete it here.
45-//
46-// Contact: Jari Sundell <jaris@ifi.uio.no>
47-//
48-// Skomakerveien 33
49-// 3185 Skoppum, NORWAY
50-
51 #ifndef LIBTORRENT_TRACKER_H
52 #define LIBTORRENT_TRACKER_H
53
54@@ -148,8 +112,8 @@ protected:
55
56 void set_group(uint32_t v) { m_group = v; }
57
58- void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 3600); }
59- void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 1800); }
60+ void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 8 * 3600); }
61+ void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 4 * 3600); }
62
63 int m_flags;
64
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch
new file mode 100644
index 0000000000..885b1828d1
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch
@@ -0,0 +1,123 @@
1From efc75948253c1a8db482daabf45d9eabaaf4b099 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Wed, 17 Jul 2019 19:41:04 +0200
4Subject: [PATCH] Close log files when reusing a name.
5
6---
7 src/torrent/utils/log.cc | 20 ++++++++++++++++----
8 src/torrent/utils/log.h | 7 +++++++
9 test/torrent/tracker_timeout_test.cc | 8 ++++----
10 test/torrent/utils/log_test.cc | 12 ++++++------
11 4 files changed, 33 insertions(+), 14 deletions(-)
12
13diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
14index 58b563a6..5169a730 100644
15--- a/src/torrent/utils/log.cc
16+++ b/src/torrent/utils/log.cc
17@@ -294,12 +294,16 @@ log_open_output(const char* name, log_slot slot) {
18 throw input_error("Cannot open more than 64 log output handlers.");
19 }
20
21- if (log_find_output_name(name) != log_outputs.end()) {
22- pthread_mutex_unlock(&log_mutex);
23- throw input_error("Log name already used.");
24+ log_output_list::iterator itr = log_find_output_name(name);
25+
26+ if (itr == log_outputs.end()) {
27+ log_outputs.push_back(std::make_pair(name, slot));
28+ } else {
29+ // by replacing the "write" slot binding, the old file gets closed
30+ // (handles are shared pointers)
31+ itr->second = slot;
32 }
33
34- log_outputs.push_back(std::make_pair(name, slot));
35 log_rebuild_cache();
36
37 pthread_mutex_unlock(&log_mutex);
38@@ -307,6 +311,14 @@ log_open_output(const char* name, log_slot slot) {
39
40 void
41 log_close_output(const char* name) {
42+ pthread_mutex_lock(&log_mutex);
43+
44+ log_output_list::iterator itr = log_find_output_name(name);
45+
46+ if (itr != log_outputs.end())
47+ log_outputs.erase(itr);
48+
49+ pthread_mutex_unlock(&log_mutex);
50 }
51
52 void
53diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
54index a053d6ec..430bda5e 100644
55--- a/src/torrent/utils/log.h
56+++ b/src/torrent/utils/log.h
57@@ -229,6 +229,7 @@ void log_cleanup() LIBTORRENT_EXPORT;
58
59 void log_open_output(const char* name, log_slot slot) LIBTORRENT_EXPORT;
60 void log_close_output(const char* name) LIBTORRENT_EXPORT;
61+void log_close_output_str(const std::string name) LIBTORRENT_EXPORT;
62
63 void log_add_group_output(int group, const char* name) LIBTORRENT_EXPORT;
64 void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
65@@ -240,6 +241,12 @@ void log_open_file_output(const char* name, const char* filename) LIBTORR
66 void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
67 log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
68
69+//
70+// Implementation:
71+//
72+
73+inline void log_close_output_str(const std::string name) { log_close_output(name.c_str()); }
74+
75 }
76
77 #endif
78diff --git a/test/torrent/tracker_timeout_test.cc b/test/torrent/tracker_timeout_test.cc
79index 081b9301..cd060006 100644
80--- a/test/torrent/tracker_timeout_test.cc
81+++ b/test/torrent/tracker_timeout_test.cc
82@@ -29,13 +29,13 @@ tracker_timeout_test::test_set_timeout() {
83
84 tracker.set_new_normal_interval(100);
85 CPPUNIT_ASSERT(tracker.normal_interval() == 600);
86- tracker.set_new_normal_interval(4000);
87- CPPUNIT_ASSERT(tracker.normal_interval() == 3600);
88+ tracker.set_new_normal_interval(8 * 4000);
89+ CPPUNIT_ASSERT(tracker.normal_interval() == 8 * 3600);
90
91 tracker.set_new_min_interval(100);
92 CPPUNIT_ASSERT(tracker.min_interval() == 300);
93- tracker.set_new_min_interval(4000);
94- CPPUNIT_ASSERT(tracker.min_interval() == 1800);
95+ tracker.set_new_min_interval(4 * 4000);
96+ CPPUNIT_ASSERT(tracker.min_interval() == 4 * 3600);
97 }
98
99 void
100diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
101index 9b99c245..24c22b59 100644
102--- a/test/torrent/utils/log_test.cc
103+++ b/test/torrent/utils/log_test.cc
104@@ -75,13 +75,13 @@ utils_log_test::test_output_open() {
105 // Test inserting duplicate names, should catch.
106 // CPPUNIT_ASSERT_THROW(torrent::log_open_output("test_output_1", torrent::log_slot());, torrent::input_error);
107
108- try {
109- torrent::log_open_output("test_output_1", torrent::log_slot());
110- } catch (torrent::input_error& e) {
111- return;
112- }
113+ // try {
114+ // torrent::log_open_output("test_output_1", torrent::log_slot());
115+ // } catch (torrent::input_error& e) {
116+ // return;
117+ // }
118
119- CPPUNIT_ASSERT(false);
120+ // CPPUNIT_ASSERT(false);
121
122 // Test more than 64 entries.
123 }
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch
new file mode 100644
index 0000000000..ffe6b3f22e
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch
@@ -0,0 +1,30 @@
1From 7faa9c58ce098bbdeff83b6add72f3075b47881d Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Fri, 19 Jul 2019 13:38:12 +0200
4Subject: [PATCH] Bumped to version 0.13.8.
5
6---
7 configure.ac | 8 ++++----
8 1 file changed, 4 insertions(+), 4 deletions(-)
9
10diff --git a/configure.ac b/configure.ac
11index b885714d..4ed08124 100644
12--- a/configure.ac
13+++ b/configure.ac
14@@ -1,12 +1,12 @@
15-AC_INIT(libtorrent, 0.13.7, sundell.software@gmail.com)
16+AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com)
17
18 LT_INIT([disable-static])
19
20 dnl Find a better way to do this
21-AC_DEFINE(PEER_NAME, "-lt0D70-", Identifier that is part of the default peer id)
22-AC_DEFINE(PEER_VERSION, "lt\x0D\x70", 4 byte client and version identifier for DHT)
23+AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id)
24+AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT)
25
26-LIBTORRENT_CURRENT=20
27+LIBTORRENT_CURRENT=21
28 LIBTORRENT_REVISION=0
29 LIBTORRENT_AGE=0
30
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch
new file mode 100644
index 0000000000..c8884d856d
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch
@@ -0,0 +1,109 @@
1From 7667094274879fe158e718bf2765d35f82d924bd Mon Sep 17 00:00:00 2001
2From: nicholi <nschell@gmail.com>
3Date: Tue, 23 Jul 2019 23:59:16 -0700
4Subject: [PATCH] Allow logs to be appended rather than overwritten.
5
6---
7 src/torrent/utils/log.cc | 13 +++++++++++++
8 src/torrent/utils/log.h | 1 +
9 test/torrent/utils/log_test.cc | 35 ++++++++++++++++++++++++++++++++++
10 test/torrent/utils/log_test.h | 2 ++
11 4 files changed, 51 insertions(+)
12
13diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
14index 5169a730..a900c109 100644
15--- a/src/torrent/utils/log.cc
16+++ b/src/torrent/utils/log.cc
17@@ -428,6 +428,19 @@ log_open_file_output(const char* name, const char* filename) {
18 std::placeholders::_3));
19 }
20
21+void
22+log_open_file_output_append(const char* name, const char* filename) {
23+ std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename, std::ofstream::out | std::ofstream::app));
24+
25+ if (!outfile->good())
26+ throw input_error("Could not open log file '" + std::string(filename) + "'.");
27+
28+ log_open_output(name, std::bind(&log_file_write, outfile,
29+ std::placeholders::_1,
30+ std::placeholders::_2,
31+ std::placeholders::_3));
32+}
33+
34 void
35 log_open_gz_file_output(const char* name, const char* filename) {
36 std::shared_ptr<log_gz_output> outfile(new log_gz_output(filename));
37diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
38index 430bda5e..531c8565 100644
39--- a/src/torrent/utils/log.h
40+++ b/src/torrent/utils/log.h
41@@ -238,6 +238,7 @@ void log_add_child(int group, int child) LIBTORRENT_EXPORT;
42 void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
43
44 void log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
45+void log_open_file_output_append(const char* name, const char* filename) LIBTORRENT_EXPORT;
46 void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
47 log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
48
49diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
50index 24c22b59..aa13fff8 100644
51--- a/test/torrent/utils/log_test.cc
52+++ b/test/torrent/utils/log_test.cc
53@@ -155,3 +155,38 @@ utils_log_test::test_file_output() {
54
55 CPPUNIT_ASSERT_MESSAGE(buffer, std::string(buffer).find("test_file") != std::string::npos);
56 }
57+
58+void
59+utils_log_test::test_file_output_append() {
60+ std::string filename = "utils_log_test.XXXXXX";
61+
62+ mktemp(&*filename.begin());
63+
64+ torrent::log_open_file_output_append("test_file", filename.c_str());
65+ torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
66+
67+ lt_log_print(GROUP_PARENT_1, "test_line_1");
68+
69+ torrent::log_cleanup(); // To ensure we flush the buffers.
70+
71+ // re-open and write 2nd line
72+ torrent::log_open_file_output_append("test_file", filename.c_str());
73+ torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
74+
75+ lt_log_print(GROUP_PARENT_1, "test_line_2");
76+
77+ torrent::log_cleanup(); // To ensure we flush the buffers.
78+
79+ std::ifstream temp_file(filename.c_str());
80+
81+ CPPUNIT_ASSERT(temp_file.good());
82+
83+ char buffer_line1[256];
84+ temp_file.getline(buffer_line1, 256);
85+
86+ char buffer_line2[256];
87+ temp_file.getline(buffer_line2, 256);
88+
89+ CPPUNIT_ASSERT_MESSAGE(buffer_line1, std::string(buffer_line1).find("test_line_1") != std::string::npos);
90+ CPPUNIT_ASSERT_MESSAGE(buffer_line2, std::string(buffer_line2).find("test_line_2") != std::string::npos);
91+}
92diff --git a/test/torrent/utils/log_test.h b/test/torrent/utils/log_test.h
93index 3a66cc24..d4cb3bc6 100644
94--- a/test/torrent/utils/log_test.h
95+++ b/test/torrent/utils/log_test.h
96@@ -10,6 +10,7 @@ class utils_log_test : public CppUnit::TestFixture {
97 CPPUNIT_TEST(test_print);
98 CPPUNIT_TEST(test_children);
99 CPPUNIT_TEST(test_file_output);
100+ CPPUNIT_TEST(test_file_output_append);
101 CPPUNIT_TEST_SUITE_END();
102
103 public:
104@@ -22,4 +23,5 @@ public:
105 void test_print();
106 void test_children();
107 void test_file_output();
108+ void test_file_output_append();
109 };
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch
new file mode 100644
index 0000000000..9859f954c9
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch
@@ -0,0 +1,101 @@
1From df54913c34c8b584d6d2072a65ad1590766780c5 Mon Sep 17 00:00:00 2001
2From: nicholi <nschell@gmail.com>
3Date: Fri, 26 Jul 2019 00:50:52 -0700
4Subject: [PATCH] Removed log append function. Added append parameter with
5 default value (false) to log_open_file functions.
6
7---
8 src/torrent/utils/log.cc | 26 ++++++++------------------
9 src/torrent/utils/log.h | 5 ++---
10 test/torrent/utils/log_test.cc | 4 ++--
11 3 files changed, 12 insertions(+), 23 deletions(-)
12
13diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
14index a900c109..6c605474 100644
15--- a/src/torrent/utils/log.cc
16+++ b/src/torrent/utils/log.cc
17@@ -73,7 +73,7 @@ struct log_cache_entry {
18 };
19
20 struct log_gz_output {
21- log_gz_output(const char* filename) { gz_file = gzopen(filename, "w"); }
22+ log_gz_output(const char* filename, bool append) { gz_file = gzopen(filename, append ? "a" : "w"); }
23 ~log_gz_output() { if (gz_file != NULL) gzclose(gz_file); }
24
25 bool is_valid() { return gz_file != Z_NULL; }
26@@ -416,8 +416,11 @@ log_gz_file_write(std::shared_ptr<log_gz_output>& outfile, const char* data, siz
27 }
28
29 void
30-log_open_file_output(const char* name, const char* filename) {
31- std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename));
32+log_open_file_output(const char* name, const char* filename, bool append) {
33+ std::ios_base::openmode mode = std::ofstream::out;
34+ if (append)
35+ mode |= std::ofstream::app;
36+ std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename, mode));
37
38 if (!outfile->good())
39 throw input_error("Could not open log file '" + std::string(filename) + "'.");
40@@ -429,21 +432,8 @@ log_open_file_output(const char* name, const char* filename) {
41 }
42
43 void
44-log_open_file_output_append(const char* name, const char* filename) {
45- std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename, std::ofstream::out | std::ofstream::app));
46-
47- if (!outfile->good())
48- throw input_error("Could not open log file '" + std::string(filename) + "'.");
49-
50- log_open_output(name, std::bind(&log_file_write, outfile,
51- std::placeholders::_1,
52- std::placeholders::_2,
53- std::placeholders::_3));
54-}
55-
56-void
57-log_open_gz_file_output(const char* name, const char* filename) {
58- std::shared_ptr<log_gz_output> outfile(new log_gz_output(filename));
59+log_open_gz_file_output(const char* name, const char* filename, bool append) {
60+ std::shared_ptr<log_gz_output> outfile(new log_gz_output(filename, append));
61
62 if (!outfile->is_valid())
63 throw input_error("Could not open log gzip file '" + std::string(filename) + "'.");
64diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
65index 531c8565..0dfdc86b 100644
66--- a/src/torrent/utils/log.h
67+++ b/src/torrent/utils/log.h
68@@ -237,9 +237,8 @@ void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
69 void log_add_child(int group, int child) LIBTORRENT_EXPORT;
70 void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
71
72-void log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
73-void log_open_file_output_append(const char* name, const char* filename) LIBTORRENT_EXPORT;
74-void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
75+void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
76+void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
77 log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
78
79 //
80diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
81index aa13fff8..9f975636 100644
82--- a/test/torrent/utils/log_test.cc
83+++ b/test/torrent/utils/log_test.cc
84@@ -162,7 +162,7 @@ utils_log_test::test_file_output_append() {
85
86 mktemp(&*filename.begin());
87
88- torrent::log_open_file_output_append("test_file", filename.c_str());
89+ torrent::log_open_file_output("test_file", filename.c_str(), false);
90 torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
91
92 lt_log_print(GROUP_PARENT_1, "test_line_1");
93@@ -170,7 +170,7 @@ utils_log_test::test_file_output_append() {
94 torrent::log_cleanup(); // To ensure we flush the buffers.
95
96 // re-open and write 2nd line
97- torrent::log_open_file_output_append("test_file", filename.c_str());
98+ torrent::log_open_file_output("test_file", filename.c_str(), true);
99 torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
100
101 lt_log_print(GROUP_PARENT_1, "test_line_2");
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch
new file mode 100644
index 0000000000..6b1578bde7
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch
@@ -0,0 +1,7365 @@
1From b0f945e11d6afe43c917b58291c6fbcf5468a908 Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Fri, 23 Aug 2019 23:23:48 +0900
4Subject: [PATCH] Backport changes from feature-bind. (#200)
5
6---
7 .dir-locals.el | 7 +
8 Makefile.am | 1 +
9 configure.ac | 40 +-
10 extra/corrupt_file.cc | 2 +-
11 rak/file_stat.h | 2 +-
12 rak/fs_stat.h | 2 +-
13 rak/partial_queue.h | 2 +-
14 rak/path.h | 2 +-
15 rak/priority_queue_default.h | 2 +-
16 rak/socket_address.h | 49 +-
17 rak/timer.h | 2 +-
18 scripts/checks.m4 | 4 +-
19 scripts/rak_cxx.m4 | 47 --
20 scripts/ssl.m4 | 38 ++
21 src/data/chunk_list.cc | 2 -
22 src/data/chunk_list.h | 2 +-
23 src/data/chunk_list_node.h | 2 +-
24 src/data/hash_check_queue.h | 2 +-
25 src/data/hash_queue.cc | 2 -
26 src/data/hash_queue.h | 2 +-
27 src/data/hash_queue_node.h | 4 +-
28 src/data/hash_torrent.cc | 2 -
29 src/data/hash_torrent.h | 4 +-
30 src/data/memory_chunk.h | 2 +-
31 src/data/socket_file.h | 2 +-
32 src/dht/dht_hash_map.h | 57 +-
33 src/download/chunk_selector.h | 2 +-
34 src/download/chunk_statistics.h | 2 +-
35 src/download/delegator.cc | 2 +-
36 src/download/delegator.h | 2 +-
37 src/download/download_constructor.h | 2 +-
38 src/globals.cc | 15 +-
39 src/globals.h | 36 --
40 src/manager.cc | 36 --
41 src/net/Makefile.am | 2 +
42 src/net/data_buffer.h | 2 +-
43 src/net/listen.cc | 40 +-
44 src/net/listen.h | 4 +-
45 src/net/protocol_buffer.h | 2 +-
46 src/net/socket_base.h | 2 +-
47 src/net/socket_fd.cc | 10 +
48 src/net/socket_fd.h | 6 +
49 src/net/socket_listen.cc | 137 +++++
50 src/net/socket_listen.h | 46 ++
51 src/net/socket_set.h | 2 +-
52 src/net/throttle_node.h | 2 +-
53 src/protocol/handshake.cc | 13 +-
54 src/protocol/handshake_manager.cc | 56 +-
55 src/protocol/handshake_manager.h | 40 +-
56 src/protocol/peer_connection_base.cc | 2 -
57 src/protocol/request_list.cc | 38 +-
58 src/torrent/Makefile.am | 1 +
59 src/torrent/common.h | 5 +-
60 src/torrent/connection_manager.h | 2 +-
61 src/torrent/data/download_data.h | 2 +-
62 src/torrent/data/file_list.cc | 2 -
63 src/torrent/data/transfer_list.h | 3 +-
64 src/torrent/download.cc | 4 +-
65 src/torrent/download/choke_group.cc | 2 +-
66 src/torrent/download/choke_group.h | 2 +-
67 src/torrent/download/choke_queue.cc | 3 +-
68 src/torrent/download/choke_queue.h | 5 +-
69 src/torrent/download/group_entry.h | 3 +-
70 src/torrent/download/resource_manager.cc | 1 -
71 src/torrent/download/resource_manager.h | 2 +-
72 src/torrent/download_info.h | 4 +-
73 src/torrent/error.cc | 6 +-
74 src/torrent/error.h | 7 +-
75 src/torrent/event.cc | 19 +
76 src/torrent/event.h | 82 ++-
77 src/torrent/http.h | 2 +-
78 src/torrent/net/Makefile.am | 18 +-
79 src/torrent/net/address_info.cc | 43 ++
80 src/torrent/net/address_info.h | 69 +++
81 src/torrent/net/fd.cc | 209 +++++++
82 src/torrent/net/fd.h | 63 ++
83 src/torrent/net/socket_address.cc | 559 ++++++++++++++++++
84 src/torrent/net/socket_address.h | 229 +++++++
85 src/torrent/net/socket_address_key.h | 2 +-
86 src/torrent/net/socket_event.cc | 29 +
87 src/torrent/net/socket_event.h | 31 +
88 src/torrent/net/types.h | 33 ++
89 src/torrent/object.h | 21 +-
90 src/torrent/peer/client_list.cc | 2 +-
91 src/torrent/peer/connection_list.h | 3 +-
92 src/torrent/peer/peer_list.cc | 7 +-
93 src/torrent/poll.h | 3 +-
94 src/torrent/torrent.cc | 42 +-
95 src/torrent/torrent.h | 11 +-
96 src/torrent/tracker.h | 2 +-
97 src/torrent/tracker_controller.h | 3 +-
98 src/torrent/tracker_list.h | 2 +-
99 src/torrent/utils/Makefile.am | 5 +-
100 src/torrent/utils/directory_events.h | 3 +-
101 src/torrent/utils/log.cc | 66 +--
102 src/torrent/utils/log.h | 98 ++-
103 src/torrent/utils/log_buffer.cc | 55 +-
104 src/torrent/utils/log_buffer.h | 52 +-
105 src/torrent/utils/net.cc | 72 ---
106 src/torrent/utils/net.h | 56 --
107 src/torrent/utils/option_strings.cc | 63 +-
108 src/torrent/utils/option_strings.h | 7 +-
109 src/torrent/utils/random.cc | 29 +
110 src/torrent/utils/random.h | 15 +
111 src/torrent/utils/ranges.h | 1 -
112 src/torrent/utils/resume.cc | 2 -
113 src/torrent/utils/signal_bitfield.h | 3 +-
114 src/torrent/utils/thread_base.h | 3 +-
115 src/utils/instrumentation.cc | 2 -
116 src/utils/instrumentation.h | 3 +-
117 src/utils/queue_buckets.h | 4 +-
118 src/utils/sha_fast.h | 2 +-
119 test/Makefile.am | 29 +-
120 test/data/hash_check_queue_test.cc | 2 +-
121 test/data/hash_queue_test.cc | 2 +-
122 test/helpers/expect_fd.h | 107 ++++
123 test/helpers/expect_utils.h | 13 +
124 test/helpers/mock_compare.h | 96 +++
125 test/helpers/mock_function.cc | 170 ++++++
126 test/helpers/mock_function.h | 133 +++++
127 test/helpers/network.h | 182 ++++++
128 test/helpers/progress_listener.cc | 63 ++
129 test/helpers/progress_listener.h | 47 ++
130 test/helpers/test_fixture.cc | 18 +
131 test/helpers/test_fixture.h | 14 +
132 test/helpers/utils.h | 60 ++
133 test/main.cc | 82 ++-
134 test/net/test_socket_listen.cc | 398 +++++++++++++
135 test/net/test_socket_listen.h | 44 ++
136 test/torrent/net/test_address_info.cc | 62 ++
137 test/torrent/net/test_address_info.h | 19 +
138 test/torrent/net/test_fd.cc | 24 +
139 test/torrent/net/test_fd.h | 12 +
140 test/torrent/net/test_socket_address.cc | 383 ++++++++++++
141 test/torrent/net/test_socket_address.h | 43 ++
142 test/torrent/net/test_socket_address_key.cc | 87 ---
143 test/torrent/object_stream_test.cc | 4 +-
144 test/torrent/tracker_controller_features.cc | 2 +-
145 test/torrent/tracker_controller_requesting.cc | 2 +-
146 test/torrent/tracker_controller_test.cc | 2 +-
147 test/torrent/tracker_list_features_test.cc | 2 +-
148 test/torrent/utils/directory_events_test.cc | 4 +-
149 test/torrent/utils/log_buffer_test.h | 17 -
150 test/torrent/utils/log_test.cc | 4 +-
151 test/torrent/utils/net_test.cc | 32 -
152 test/torrent/utils/net_test.h | 15 -
153 test/torrent/utils/option_strings_test.cc | 3 +-
154 test/torrent/utils/test_extents.cc | 2 +-
155 ...{log_buffer_test.cc => test_log_buffer.cc} | 14 +-
156 test/torrent/utils/test_log_buffer.h | 17 +
157 test/torrent/utils/test_uri_parser.cc | 2 +-
158 test/torrent/utils/thread_base_test.cc | 3 +-
159 152 files changed, 3968 insertions(+), 1110 deletions(-)
160 create mode 100644 .dir-locals.el
161 create mode 100644 scripts/ssl.m4
162 create mode 100644 src/net/socket_listen.cc
163 create mode 100644 src/net/socket_listen.h
164 create mode 100644 src/torrent/event.cc
165 create mode 100644 src/torrent/net/address_info.cc
166 create mode 100644 src/torrent/net/address_info.h
167 create mode 100644 src/torrent/net/fd.cc
168 create mode 100644 src/torrent/net/fd.h
169 create mode 100644 src/torrent/net/socket_address.cc
170 create mode 100644 src/torrent/net/socket_address.h
171 create mode 100644 src/torrent/net/socket_event.cc
172 create mode 100644 src/torrent/net/socket_event.h
173 create mode 100644 src/torrent/net/types.h
174 delete mode 100644 src/torrent/utils/net.cc
175 delete mode 100644 src/torrent/utils/net.h
176 create mode 100644 src/torrent/utils/random.cc
177 create mode 100644 src/torrent/utils/random.h
178 create mode 100644 test/helpers/expect_fd.h
179 create mode 100644 test/helpers/expect_utils.h
180 create mode 100644 test/helpers/mock_compare.h
181 create mode 100644 test/helpers/mock_function.cc
182 create mode 100644 test/helpers/mock_function.h
183 create mode 100644 test/helpers/network.h
184 create mode 100644 test/helpers/progress_listener.cc
185 create mode 100644 test/helpers/progress_listener.h
186 create mode 100644 test/helpers/test_fixture.cc
187 create mode 100644 test/helpers/test_fixture.h
188 create mode 100644 test/helpers/utils.h
189 create mode 100644 test/net/test_socket_listen.cc
190 create mode 100644 test/net/test_socket_listen.h
191 create mode 100644 test/torrent/net/test_address_info.cc
192 create mode 100644 test/torrent/net/test_address_info.h
193 create mode 100644 test/torrent/net/test_fd.cc
194 create mode 100644 test/torrent/net/test_fd.h
195 create mode 100644 test/torrent/net/test_socket_address.cc
196 create mode 100644 test/torrent/net/test_socket_address.h
197 delete mode 100644 test/torrent/net/test_socket_address_key.cc
198 delete mode 100644 test/torrent/utils/log_buffer_test.h
199 delete mode 100644 test/torrent/utils/net_test.cc
200 delete mode 100644 test/torrent/utils/net_test.h
201 rename test/torrent/utils/{log_buffer_test.cc => test_log_buffer.cc} (86%)
202 create mode 100644 test/torrent/utils/test_log_buffer.h
203
204diff --git a/.dir-locals.el b/.dir-locals.el
205new file mode 100644
206index 00000000..af1189f2
207--- /dev/null
208+++ b/.dir-locals.el
209@@ -0,0 +1,7 @@
210+;;; Directory Local Variables
211+;;; For more information see (info "(emacs) Directory Variables")
212+
213+((c++-mode
214+ (flycheck-clang-language-standard . "c++11")
215+ (flycheck-gcc-language-standard . "c++11")))
216+
217diff --git a/Makefile.am b/Makefile.am
218index f175e634..9507b9ea 100644
219--- a/Makefile.am
220+++ b/Makefile.am
221@@ -8,6 +8,7 @@ EXTRA_DIST= \
222 scripts/checks.m4 \
223 scripts/common.m4 \
224 scripts/attributes.m4 \
225+ scripts/ssl.m4 \
226 doc/main.xml \
227 doc/http.xml \
228 doc/torrent.xml \
229diff --git a/configure.ac b/configure.ac
230index 4ed08124..620ca552 100644
231--- a/configure.ac
232+++ b/configure.ac
233@@ -17,7 +17,7 @@ AC_SUBST(LIBTORRENT_CURRENT)
234 AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO)
235 AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO)
236
237-AM_INIT_AUTOMAKE
238+AM_INIT_AUTOMAKE([serial-tests])
239 AC_CONFIG_HEADERS(config.h)
240
241 AC_PROG_CXX
242@@ -35,7 +35,6 @@ RAK_ENABLE_EXTRA_DEBUG
243 RAK_ENABLE_WERROR
244
245 RAK_CHECK_CXX11
246-RAK_CHECK_TR1_LIB
247
248 AC_SYS_LARGEFILE
249
250@@ -67,41 +66,8 @@ CFLAGS="$PTHREAD_CFLAGS $CPPUNIT_CFLAGS $CFLAGS"
251 CXXFLAGS="$PTHREAD_CFLAGS $CPPUNIT_CFLAGS $CXXFLAGS"
252 LIBS="$PTHREAD_LIBS $CPPUNIT_LIBS $LIBS"
253
254-AC_ARG_ENABLE(openssl,
255- [ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
256- [
257- if test "$enableval" = "yes"; then
258-dnl move to scripts.
259- PKG_CHECK_MODULES(OPENSSL, libcrypto,
260- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
261- LIBS="$LIBS $OPENSSL_LIBS")
262-
263- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
264- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
265- AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
266-
267- else
268- AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
269- fi
270- ],[
271- PKG_CHECK_MODULES(OPENSSL, libcrypto,
272- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
273- LIBS="$LIBS $OPENSSL_LIBS")
274-
275- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
276- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
277- AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
278- ]
279-)
280-
281-AC_ARG_ENABLE(cyrus-rc4,
282- [ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.],
283- [
284- CXXFLAGS="$CXXFLAGS -I${enableval}/include";
285- LIBS="$LIBS -lrc4 -L${enableval}/lib"
286- AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.)
287- ]
288-)
289+TORRENT_ARG_OPENSSL
290+TORRENT_ARG_CYRUS_RC4
291
292 AC_CHECK_FUNCS(posix_memalign)
293
294diff --git a/extra/corrupt_file.cc b/extra/corrupt_file.cc
295index 2a818cc7..7ae906e6 100644
296--- a/extra/corrupt_file.cc
297+++ b/extra/corrupt_file.cc
298@@ -1,6 +1,6 @@
299 #include <iostream>
300 #include <stdexcept>
301-#include <inttypes.h>
302+#include <cinttypes>
303 #include <stdio.h>
304 #include <stdlib.h>
305 #include <fcntl.h>
306diff --git a/rak/file_stat.h b/rak/file_stat.h
307index 5ad45e8f..f1ad8c2b 100644
308--- a/rak/file_stat.h
309+++ b/rak/file_stat.h
310@@ -38,7 +38,7 @@
311 #define RAK_FILE_STAT_H
312
313 #include <string>
314-#include <inttypes.h>
315+#include <cinttypes>
316 #include <sys/stat.h>
317
318 namespace rak {
319diff --git a/rak/fs_stat.h b/rak/fs_stat.h
320index 5e844277..2d73ff1b 100644
321--- a/rak/fs_stat.h
322+++ b/rak/fs_stat.h
323@@ -38,7 +38,7 @@
324 #define RAK_FS_STAT_H
325
326 #include <string>
327-#include <inttypes.h>
328+#include <cinttypes>
329
330 #include <rak/error_number.h>
331
332diff --git a/rak/partial_queue.h b/rak/partial_queue.h
333index 6650a633..1abfdddf 100644
334--- a/rak/partial_queue.h
335+++ b/rak/partial_queue.h
336@@ -39,7 +39,7 @@
337
338 #include <cstring>
339 #include <stdexcept>
340-#include <inttypes.h>
341+#include <cinttypes>
342
343 namespace rak {
344
345diff --git a/rak/path.h b/rak/path.h
346index bfe8ccc1..64daf355 100644
347--- a/rak/path.h
348+++ b/rak/path.h
349@@ -99,7 +99,7 @@ path_expand(const char* src, char* first, char* last) {
350 src++;
351 }
352
353- return std::max(first + strlcpy(first, src, std::distance(first, last)), last);
354+ return std::min(first + strlcpy(first, src, std::distance(first, last)), last);
355 }
356
357 }
358diff --git a/rak/priority_queue_default.h b/rak/priority_queue_default.h
359index 01a0070e..a7bba0ce 100644
360--- a/rak/priority_queue_default.h
361+++ b/rak/priority_queue_default.h
362@@ -37,7 +37,7 @@
363 #ifndef RAK_PRIORITY_QUEUE_DEFAULT_H
364 #define RAK_PRIORITY_QUEUE_DEFAULT_H
365
366-#include lt_tr1_functional
367+#include <functional>
368 #include <rak/allocators.h>
369 #include <rak/priority_queue.h>
370 #include <rak/timer.h>
371diff --git a/rak/socket_address.h b/rak/socket_address.h
372index 961c53b2..8eb60116 100644
373--- a/rak/socket_address.h
374+++ b/rak/socket_address.h
375@@ -47,9 +47,12 @@
376 #ifndef RAK_SOCKET_ADDRESS_H
377 #define RAK_SOCKET_ADDRESS_H
378
379+#include <cinttypes>
380+#include <cstdint>
381 #include <cstring>
382-#include <string>
383 #include <stdexcept>
384+#include <string>
385+
386 #include <arpa/inet.h>
387 #include <netinet/in.h>
388 #include <sys/types.h>
389@@ -84,7 +87,6 @@ public:
390
391 bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; }
392
393- // Should we need to set AF_UNSPEC?
394 void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); }
395
396 sa_family_t family() const { return m_sockaddr.sa_family; }
397@@ -124,6 +126,7 @@ public:
398 // extranous bytes and ensure it does not go beyond the size of this
399 // struct.
400 void copy(const socket_address& src, size_t length);
401+ void copy_sockaddr(const sockaddr* src);
402
403 static socket_address* cast_from(sockaddr* sa) { return reinterpret_cast<socket_address*>(sa); }
404 static const socket_address* cast_from(const sockaddr* sa) { return reinterpret_cast<const socket_address*>(sa); }
405@@ -220,6 +223,8 @@ public:
406
407 void set_address_any() { set_port(0); set_address(in6addr_any); }
408
409+ std::string pretty_address_str() const;
410+
411 sa_family_t family() const { return m_sockaddr.sin6_family; }
412 void set_family() { m_sockaddr.sin6_family = AF_INET6; }
413
414@@ -340,7 +345,7 @@ socket_address::pretty_address_str() const {
415 case af_inet:
416 return sa_inet()->address_str();
417 case af_inet6:
418- return sa_inet6()->address_str();
419+ return sa_inet6()->pretty_address_str();
420 case af_unspec:
421 return std::string("unspec");
422 default:
423@@ -380,13 +385,16 @@ socket_address::length() const {
424 inline void
425 socket_address::copy(const socket_address& src, size_t length) {
426 length = std::min(length, sizeof(socket_address));
427-
428- // Does this get properly optimized?
429+
430 std::memset(this, 0, sizeof(socket_address));
431 std::memcpy(this, &src, length);
432 }
433
434-// Should we be able to compare af_unspec?
435+inline void
436+socket_address::copy_sockaddr(const sockaddr* src) {
437+ std::memset(this, 0, sizeof(socket_address));
438+ std::memcpy(this, src, socket_address::cast_from(src)->length());
439+}
440
441 inline bool
442 socket_address::operator == (const socket_address& rhs) const {
443@@ -488,6 +496,35 @@ socket_address_inet6::set_address_c_str(const char* a) {
444 return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr);
445 }
446
447+inline std::string
448+socket_address_inet6::pretty_address_str() const {
449+ char buf[INET6_ADDRSTRLEN + 2 + 6];
450+
451+ if (inet_ntop(family(), &m_sockaddr.sin6_addr, buf + 1, INET6_ADDRSTRLEN) == NULL)
452+ return std::string();
453+
454+ buf[0] = '[';
455+
456+ char* last_char = (char*)std::memchr(buf + 1, 0, INET6_ADDRSTRLEN);
457+
458+ // TODO: Throw exception here.
459+
460+ if (last_char == NULL || last_char >= buf + 1 + INET6_ADDRSTRLEN)
461+ throw std::logic_error("inet_ntop for inet6 returned bad buffer");
462+
463+ *(last_char++) = ']';
464+
465+ if (!is_port_any()) {
466+ if (snprintf(last_char, 7, ":%" PRIu16, port()) == -1)
467+ return std::string("error"); // TODO: Throw here.
468+
469+ } else {
470+ *last_char = '\0';
471+ }
472+
473+ return std::string(buf);
474+}
475+
476 inline socket_address
477 socket_address_inet6::normalize_address() const {
478 const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(m_sockaddr.sin6_addr.s6_addr);
479diff --git a/rak/timer.h b/rak/timer.h
480index e25ad2e6..842a2e53 100644
481--- a/rak/timer.h
482+++ b/rak/timer.h
483@@ -38,7 +38,7 @@
484 #define RAK_TIMER_H
485
486 #include <limits>
487-#include <inttypes.h>
488+#include <cinttypes>
489 #include <sys/time.h>
490
491 namespace rak {
492diff --git a/scripts/checks.m4 b/scripts/checks.m4
493index 83be8461..98ef17f8 100644
494--- a/scripts/checks.m4
495+++ b/scripts/checks.m4
496@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
497 [
498 AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
499 AC_MSG_RESULT(yes)
500+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
501 ], [
502 AC_MSG_RESULT(no)
503 ])
504@@ -137,7 +138,6 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
505 [
506 if test "$withval" = "yes"; then
507 TORRENT_CHECK_KQUEUE
508- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
509 fi
510 ])
511 ])
512@@ -149,11 +149,9 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
513 [
514 if test "$withval" = "yes"; then
515 TORRENT_CHECK_KQUEUE
516- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
517 fi
518 ], [
519 TORRENT_CHECK_KQUEUE
520- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
521 ])
522 ])
523
524diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4
525index 3660f3a7..0db61b83 100644
526--- a/scripts/rak_cxx.m4
527+++ b/scripts/rak_cxx.m4
528@@ -12,50 +12,3 @@ AC_DEFUN([RAK_CHECK_CXX11], [
529 ]
530 )
531 ])
532-
533-AC_DEFUN([RAK_CHECK_TR1_LIB], [
534- AC_LANG_PUSH(C++)
535- AC_MSG_CHECKING(should use TR1 headers)
536-
537- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
538- #include <unordered_map>
539- class Foo; typedef std::unordered_map<Foo*, int> Bar;
540- Bar b1;
541- ])
542- ], [
543- AC_MSG_RESULT(no)
544- AC_DEFINE(USE_TR1_LIB, 0, Define to 1 if you need to use TR1 containers.)
545-
546- AC_DEFINE([lt_tr1_array], [<array>], [TR1 array])
547- AC_DEFINE([lt_tr1_functional], [<functional>], [TR1 functional])
548- AC_DEFINE([lt_tr1_memory], [<memory>], [TR1 memory])
549- AC_DEFINE([lt_tr1_unordered_map], [<unordered_map>], [TR1 unordered_map])
550-
551- ], [
552- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
553- #include <tr1/unordered_map>
554- class Foo; typedef std::tr1::unordered_map<Foo*, int> Bar;
555- Bar b1;
556- ])
557- ], [
558- AC_MSG_RESULT([yes])
559- AC_DEFINE(USE_TR1_LIB, 1, Define to 1 if you need to use TR1 containers.)
560-
561- AC_DEFINE([lt_tr1_array], [<tr1/array>], [TR1 array])
562- AC_DEFINE([lt_tr1_functional], [<tr1/functional>], [TR1 functional])
563- AC_DEFINE([lt_tr1_memory], [<tr1/memory>], [TR1 memory])
564- AC_DEFINE([lt_tr1_unordered_map], [<tr1/unordered_map>], [TR1 unordered_map])
565-
566- ], [
567- AC_MSG_ERROR([No support for C++11 standard library nor TR1 extensions found.])
568- ])
569- ])
570-
571- AH_VERBATIM(lt_tr1_zzz, [
572-#if USE_TR1_LIB == 1
573-namespace std { namespace tr1 {} using namespace tr1; }
574-#endif
575-])
576-
577- AC_LANG_POP(C++)
578-])
579diff --git a/scripts/ssl.m4 b/scripts/ssl.m4
580new file mode 100644
581index 00000000..f07349a1
582--- /dev/null
583+++ b/scripts/ssl.m4
584@@ -0,0 +1,38 @@
585+AC_DEFUN([TORRENT_CHECK_OPENSSL],
586+ [
587+ PKG_CHECK_MODULES(OPENSSL, libcrypto,
588+ CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
589+ LIBS="$LIBS $OPENSSL_LIBS")
590+
591+ AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
592+ AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
593+ ]
594+)
595+
596+AC_DEFUN([TORRENT_ARG_OPENSSL],
597+ [
598+ AC_ARG_ENABLE(openssl,
599+ [ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
600+ [
601+ if test "$enableval" = "yes"; then
602+ TORRENT_CHECK_OPENSSL
603+ else
604+ AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
605+ fi
606+ ],[
607+ TORRENT_CHECK_OPENSSL
608+ ])
609+ ]
610+)
611+
612+AC_DEFUN([TORRENT_ARG_CYRUS_RC4],
613+ [
614+ AC_ARG_ENABLE(cyrus-rc4,
615+ [ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.],
616+ [
617+ CXXFLAGS="$CXXFLAGS -I${enableval}/include";
618+ LIBS="$LIBS -lrc4 -L${enableval}/lib"
619+ AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.)
620+ ])
621+ ]
622+)
623diff --git a/src/data/chunk_list.cc b/src/data/chunk_list.cc
624index 00abbc2a..7622b825 100644
625--- a/src/data/chunk_list.cc
626+++ b/src/data/chunk_list.cc
627@@ -36,8 +36,6 @@
628
629 #include "config.h"
630
631-#define __STDC_FORMAT_MACROS
632-
633 #include <rak/error_number.h>
634 #include <rak/functional.h>
635
636diff --git a/src/data/chunk_list.h b/src/data/chunk_list.h
637index b6ff4cdb..4b40dc42 100644
638--- a/src/data/chunk_list.h
639+++ b/src/data/chunk_list.h
640@@ -37,9 +37,9 @@
641 #ifndef LIBTORRENT_DATA_CHUNK_LIST_H
642 #define LIBTORRENT_DATA_CHUNK_LIST_H
643
644+#include <functional>
645 #include <string>
646 #include <vector>
647-#include lt_tr1_functional
648
649 #include "chunk.h"
650 #include "chunk_handle.h"
651diff --git a/src/data/chunk_list_node.h b/src/data/chunk_list_node.h
652index 76de6671..95e4ed4f 100644
653--- a/src/data/chunk_list_node.h
654+++ b/src/data/chunk_list_node.h
655@@ -37,7 +37,7 @@
656 #ifndef LIBTORRENT_DATA_CHUNK_LIST_NODE_H
657 #define LIBTORRENT_DATA_CHUNK_LIST_NODE_H
658
659-#include <inttypes.h>
660+#include <cinttypes>
661 #include <rak/timer.h>
662
663 namespace torrent {
664diff --git a/src/data/hash_check_queue.h b/src/data/hash_check_queue.h
665index b933f137..9f28c118 100644
666--- a/src/data/hash_check_queue.h
667+++ b/src/data/hash_check_queue.h
668@@ -38,8 +38,8 @@
669 #define LIBTORRENT_DATA_HASH_CHECK_QUEUE_H
670
671 #include <deque>
672+#include <functional>
673 #include <pthread.h>
674-#include lt_tr1_functional
675
676 #include "rak/allocators.h"
677
678diff --git a/src/data/hash_queue.cc b/src/data/hash_queue.cc
679index 7dffaee4..3f54892b 100644
680--- a/src/data/hash_queue.cc
681+++ b/src/data/hash_queue.cc
682@@ -36,8 +36,6 @@
683
684 #include "config.h"
685
686-#define __STDC_FORMAT_MACROS
687-
688 #include <functional>
689 #include <rak/functional.h>
690 #include <unistd.h>
691diff --git a/src/data/hash_queue.h b/src/data/hash_queue.h
692index 6885a383..3a841967 100644
693--- a/src/data/hash_queue.h
694+++ b/src/data/hash_queue.h
695@@ -38,9 +38,9 @@
696 #define LIBTORRENT_DATA_HASH_QUEUE_H
697
698 #include <deque>
699+#include <functional>
700 #include <map>
701 #include <pthread.h>
702-#include lt_tr1_functional
703
704 #include "torrent/hash_string.h"
705 #include "hash_queue_node.h"
706diff --git a/src/data/hash_queue_node.h b/src/data/hash_queue_node.h
707index aa59a062..c8367b7c 100644
708--- a/src/data/hash_queue_node.h
709+++ b/src/data/hash_queue_node.h
710@@ -37,9 +37,9 @@
711 #ifndef LIBTORRENT_DATA_HASH_QUEUE_NODE_H
712 #define LIBTORRENT_DATA_HASH_QUEUE_NODE_H
713
714+#include <cinttypes>
715+#include <functional>
716 #include <string>
717-#include lt_tr1_functional
718-#include <inttypes.h>
719
720 #include "chunk_handle.h"
721 #include "hash_chunk.h"
722diff --git a/src/data/hash_torrent.cc b/src/data/hash_torrent.cc
723index 758a10fa..e803f1cb 100644
724--- a/src/data/hash_torrent.cc
725+++ b/src/data/hash_torrent.cc
726@@ -36,8 +36,6 @@
727
728 #include "config.h"
729
730-#define __STDC_FORMAT_MACROS
731-
732 #include "data/chunk_list.h"
733 #include "torrent/exceptions.h"
734 #include "torrent/data/download_data.h"
735diff --git a/src/data/hash_torrent.h b/src/data/hash_torrent.h
736index 6af643f2..9ce2f100 100644
737--- a/src/data/hash_torrent.h
738+++ b/src/data/hash_torrent.h
739@@ -37,9 +37,9 @@
740 #ifndef LIBTORRENT_DATA_HASH_TORRENT_H
741 #define LIBTORRENT_DATA_HASH_TORRENT_H
742
743+#include <cinttypes>
744+#include <functional>
745 #include <string>
746-#include <inttypes.h>
747-#include lt_tr1_functional
748 #include <rak/priority_queue_default.h>
749
750 #include "data/chunk_handle.h"
751diff --git a/src/data/memory_chunk.h b/src/data/memory_chunk.h
752index cc32eff1..d2b5565d 100644
753--- a/src/data/memory_chunk.h
754+++ b/src/data/memory_chunk.h
755@@ -38,7 +38,7 @@
756 #define LIBTORRENT_DATA_MEMORY_CHUNK_H
757
758 #include <algorithm>
759-#include <inttypes.h>
760+#include <cinttypes>
761 #include <sys/mman.h>
762 #include <cstddef>
763
764diff --git a/src/data/socket_file.h b/src/data/socket_file.h
765index 7b27af8c..d25c4a44 100644
766--- a/src/data/socket_file.h
767+++ b/src/data/socket_file.h
768@@ -38,7 +38,7 @@
769 #define LIBTORRENT_SOCKET_FILE_H
770
771 #include <string>
772-#include <inttypes.h>
773+#include <cinttypes>
774 #include <fcntl.h>
775 #include <sys/types.h>
776
777diff --git a/src/dht/dht_hash_map.h b/src/dht/dht_hash_map.h
778index 140f070b..1506db56 100644
779--- a/src/dht/dht_hash_map.h
780+++ b/src/dht/dht_hash_map.h
781@@ -39,20 +39,14 @@
782
783 #include "config.h"
784
785-#if HAVE_TR1
786-#include <lt_tr1_unordered_map>
787-#else
788-#include <map>
789-#endif
790-
791-#include "torrent/hash_string.h"
792+#include <unordered_map>
793
794 #include "dht_node.h"
795 #include "dht_tracker.h"
796+#include "torrent/hash_string.h"
797
798 namespace torrent {
799
800-#if HAVE_TR1
801 // Hash functions for HashString keys, and dereferencing HashString pointers.
802
803 // Since the first few bits are very similar if not identical (since the IDs
804@@ -142,53 +136,6 @@ public:
805
806 };
807
808-#else
809-
810-// Compare HashString pointers by dereferencing them.
811-struct hashstring_ptr_less : public std::binary_function<const HashString*, const HashString*, bool> {
812- size_t operator () (const HashString* one, const HashString* two) const
813- { return *one < *two; }
814-};
815-
816-class DhtNodeList : public std::map<const HashString*, DhtNode*, hashstring_ptr_less> {
817-public:
818- typedef std::map<const HashString*, DhtNode*, hashstring_ptr_less> base_type;
819-
820- // Define accessor iterator with more convenient access to the key and
821- // element values. Allows changing the map definition more easily if needed.
822- template<typename T>
823- struct accessor_wrapper : public T {
824- accessor_wrapper(const T& itr) : T(itr) { }
825-
826- const HashString& id() const { return *(**this).first; }
827- DhtNode* node() const { return (**this).second; }
828- };
829-
830- typedef accessor_wrapper<const_iterator> const_accessor;
831- typedef accessor_wrapper<iterator> accessor;
832-
833- DhtNode* add_node(DhtNode* n);
834-
835-};
836-
837-class DhtTrackerList : public std::map<HashString, DhtTracker*> {
838-public:
839- typedef std::map<HashString, DhtTracker*> base_type;
840-
841- template<typename T>
842- struct accessor_wrapper : public T {
843- accessor_wrapper(const T& itr) : T(itr) { }
844-
845- const HashString& id() const { return (**this).first; }
846- DhtTracker* tracker() const { return (**this).second; }
847- };
848-
849- typedef accessor_wrapper<const_iterator> const_accessor;
850- typedef accessor_wrapper<iterator> accessor;
851-
852-};
853-#endif // HAVE_TR1
854-
855 inline
856 DhtNode* DhtNodeList::add_node(DhtNode* n) {
857 insert(std::make_pair((const HashString*)n, (DhtNode*)n));
858diff --git a/src/download/chunk_selector.h b/src/download/chunk_selector.h
859index 52c31fd5..ab1b8c17 100644
860--- a/src/download/chunk_selector.h
861+++ b/src/download/chunk_selector.h
862@@ -37,7 +37,7 @@
863 #ifndef LIBTORRENT_DOWNLOAD_CHUNK_SELECTOR_H
864 #define LIBTORRENT_DOWNLOAD_CHUNK_SELECTOR_H
865
866-#include <inttypes.h>
867+#include <cinttypes>
868 #include <rak/partial_queue.h>
869
870 #include "torrent/bitfield.h"
871diff --git a/src/download/chunk_statistics.h b/src/download/chunk_statistics.h
872index 816ec6c9..62f76c5a 100644
873--- a/src/download/chunk_statistics.h
874+++ b/src/download/chunk_statistics.h
875@@ -37,7 +37,7 @@
876 #ifndef LIBTORRENT_DOWNLOAD_CHUNK_STATISTICS_H
877 #define LIBTORRENT_DOWNLOAD_CHUNK_STATISTICS_H
878
879-#include <inttypes.h>
880+#include <cinttypes>
881 #include <vector>
882
883 namespace torrent {
884diff --git a/src/download/delegator.cc b/src/download/delegator.cc
885index 711cd461..27ae42ec 100644
886--- a/src/download/delegator.cc
887+++ b/src/download/delegator.cc
888@@ -39,7 +39,7 @@
889 #include "config.h"
890
891 #include <algorithm>
892-#include <inttypes.h>
893+#include <cinttypes>
894
895 #include "torrent/exceptions.h"
896 #include "torrent/bitfield.h"
897diff --git a/src/download/delegator.h b/src/download/delegator.h
898index 3b997b81..b75d4c2a 100644
899--- a/src/download/delegator.h
900+++ b/src/download/delegator.h
901@@ -37,9 +37,9 @@
902 #ifndef LIBTORRENT_DELEGATOR_H
903 #define LIBTORRENT_DELEGATOR_H
904
905+#include <functional>
906 #include <string>
907 #include <vector>
908-#include lt_tr1_functional
909
910 #include "torrent/data/transfer_list.h"
911
912diff --git a/src/download/download_constructor.h b/src/download/download_constructor.h
913index 7d43aba3..6a09b7f1 100644
914--- a/src/download/download_constructor.h
915+++ b/src/download/download_constructor.h
916@@ -39,7 +39,7 @@
917
918 #include <list>
919 #include <string>
920-#include <inttypes.h>
921+#include <cinttypes>
922
923 namespace torrent {
924
925diff --git a/src/globals.cc b/src/globals.cc
926index 88130c19..20644fbd 100644
927--- a/src/globals.cc
928+++ b/src/globals.cc
929@@ -37,11 +37,24 @@
930 #include "config.h"
931
932 #include "globals.h"
933-#include "torrent/common.h"
934+#include "manager.h"
935+#include "torrent/connection_manager.h"
936+#include "torrent/event.h"
937+#include "torrent/poll.h"
938
939 namespace torrent {
940
941 LIBTORRENT_EXPORT rak::priority_queue_default taskScheduler;
942 LIBTORRENT_EXPORT rak::timer cachedTime;
943
944+void poll_event_open(Event* event) { manager->poll()->open(event); manager->connection_manager()->inc_socket_count(); }
945+void poll_event_close(Event* event) { manager->poll()->close(event); manager->connection_manager()->dec_socket_count(); }
946+void poll_event_closed(Event* event) { manager->poll()->closed(event); manager->connection_manager()->dec_socket_count(); }
947+void poll_event_insert_read(Event* event) { manager->poll()->insert_read(event); }
948+void poll_event_insert_write(Event* event) { manager->poll()->insert_write(event); }
949+void poll_event_insert_error(Event* event) { manager->poll()->insert_error(event); }
950+void poll_event_remove_read(Event* event) { manager->poll()->remove_read(event); }
951+void poll_event_remove_write(Event* event) { manager->poll()->remove_write(event); }
952+void poll_event_remove_error(Event* event) { manager->poll()->remove_error(event); }
953+
954 }
955diff --git a/src/globals.h b/src/globals.h
956index 564ac86d..e9fe1177 100644
957--- a/src/globals.h
958+++ b/src/globals.h
959@@ -1,39 +1,3 @@
960-// libTorrent - BitTorrent library
961-// Copyright (C) 2005-2011, Jari Sundell
962-//
963-// This program is free software; you can redistribute it and/or modify
964-// it under the terms of the GNU General Public License as published by
965-// the Free Software Foundation; either version 2 of the License, or
966-// (at your option) any later version.
967-//
968-// This program is distributed in the hope that it will be useful,
969-// but WITHOUT ANY WARRANTY; without even the implied warranty of
970-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
971-// GNU General Public License for more details.
972-//
973-// You should have received a copy of the GNU General Public License
974-// along with this program; if not, write to the Free Software
975-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
976-//
977-// In addition, as a special exception, the copyright holders give
978-// permission to link the code of portions of this program with the
979-// OpenSSL library under certain conditions as described in each
980-// individual source file, and distribute linked combinations
981-// including the two.
982-//
983-// You must obey the GNU General Public License in all respects for
984-// all of the code used other than OpenSSL. If you modify file(s)
985-// with this exception, you may extend this exception to your version
986-// of the file(s), but you are not obligated to do so. If you do not
987-// wish to do so, delete this exception statement from your version.
988-// If you delete this exception statement from all source files in the
989-// program, then also delete it here.
990-//
991-// Contact: Jari Sundell <jaris@ifi.uio.no>
992-//
993-// Skomakerveien 33
994-// 3185 Skoppum, NORWAY
995-
996 #ifndef LIBTORRENT_GLOBALS_H
997 #define LIBTORRENT_GLOBALS_H
998
999diff --git a/src/manager.cc b/src/manager.cc
1000index c503974d..11ef4b0f 100644
1001--- a/src/manager.cc
1002+++ b/src/manager.cc
1003@@ -1,39 +1,3 @@
1004-// libTorrent - BitTorrent library
1005-// Copyright (C) 2005-2011, Jari Sundell
1006-//
1007-// This program is free software; you can redistribute it and/or modify
1008-// it under the terms of the GNU General Public License as published by
1009-// the Free Software Foundation; either version 2 of the License, or
1010-// (at your option) any later version.
1011-//
1012-// This program is distributed in the hope that it will be useful,
1013-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1014-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1015-// GNU General Public License for more details.
1016-//
1017-// You should have received a copy of the GNU General Public License
1018-// along with this program; if not, write to the Free Software
1019-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1020-//
1021-// In addition, as a special exception, the copyright holders give
1022-// permission to link the code of portions of this program with the
1023-// OpenSSL library under certain conditions as described in each
1024-// individual source file, and distribute linked combinations
1025-// including the two.
1026-//
1027-// You must obey the GNU General Public License in all respects for
1028-// all of the code used other than OpenSSL. If you modify file(s)
1029-// with this exception, you may extend this exception to your version
1030-// of the file(s), but you are not obligated to do so. If you do not
1031-// wish to do so, delete this exception statement from your version.
1032-// If you delete this exception statement from all source files in the
1033-// program, then also delete it here.
1034-//
1035-// Contact: Jari Sundell <jaris@ifi.uio.no>
1036-//
1037-// Skomakerveien 33
1038-// 3185 Skoppum, NORWAY
1039-
1040 #include "config.h"
1041
1042 #include "torrent/exceptions.h"
1043diff --git a/src/net/Makefile.am b/src/net/Makefile.am
1044index fb4da4f3..e3a8c7e1 100644
1045--- a/src/net/Makefile.am
1046+++ b/src/net/Makefile.am
1047@@ -15,6 +15,8 @@ libsub_net_la_SOURCES = \
1048 socket_datagram.h \
1049 socket_fd.cc \
1050 socket_fd.h \
1051+ socket_listen.cc \
1052+ socket_listen.h \
1053 socket_set.cc \
1054 socket_set.h \
1055 socket_stream.cc \
1056diff --git a/src/net/data_buffer.h b/src/net/data_buffer.h
1057index d35cdc48..5dd0cb30 100644
1058--- a/src/net/data_buffer.h
1059+++ b/src/net/data_buffer.h
1060@@ -38,7 +38,7 @@
1061 #define LIBTORRENT_NET_DATA_BUFFER_H
1062
1063 #include <memory>
1064-#include <inttypes.h>
1065+#include <cinttypes>
1066
1067 namespace torrent {
1068
1069diff --git a/src/net/listen.cc b/src/net/listen.cc
1070index d424e94c..61fedbf8 100644
1071--- a/src/net/listen.cc
1072+++ b/src/net/listen.cc
1073@@ -1,39 +1,3 @@
1074-// libTorrent - BitTorrent library
1075-// Copyright (C) 2005-2011, Jari Sundell
1076-//
1077-// This program is free software; you can redistribute it and/or modify
1078-// it under the terms of the GNU General Public License as published by
1079-// the Free Software Foundation; either version 2 of the License, or
1080-// (at your option) any later version.
1081-//
1082-// This program is distributed in the hope that it will be useful,
1083-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1084-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1085-// GNU General Public License for more details.
1086-//
1087-// You should have received a copy of the GNU General Public License
1088-// along with this program; if not, write to the Free Software
1089-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1090-//
1091-// In addition, as a special exception, the copyright holders give
1092-// permission to link the code of portions of this program with the
1093-// OpenSSL library under certain conditions as described in each
1094-// individual source file, and distribute linked combinations
1095-// including the two.
1096-//
1097-// You must obey the GNU General Public License in all respects for
1098-// all of the code used other than OpenSSL. If you modify file(s)
1099-// with this exception, you may extend this exception to your version
1100-// of the file(s), but you are not obligated to do so. If you do not
1101-// wish to do so, delete this exception statement from your version.
1102-// If you delete this exception statement from all source files in the
1103-// program, then also delete it here.
1104-//
1105-// Contact: Jari Sundell <jaris@ifi.uio.no>
1106-//
1107-// Skomakerveien 33
1108-// 3185 Skoppum, NORWAY
1109-
1110 #include "config.h"
1111
1112 #define __STDC_FORMAT_MACROS
1113@@ -95,7 +59,7 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre
1114 manager->poll()->insert_read(this);
1115 manager->poll()->insert_error(this);
1116
1117- lt_log_print(LOG_CONNECTION_INFO, "listen port %" PRIu16 " opened with backlog set to %i",
1118+ lt_log_print(LOG_CONNECTION_LISTEN, "listen port %" PRIu16 " opened with backlog set to %i",
1119 m_port, backlog);
1120
1121 return true;
1122@@ -107,7 +71,7 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre
1123 get_fd().close();
1124 get_fd().clear();
1125
1126- lt_log_print(LOG_CONNECTION_INFO, "failed to open listen port");
1127+ lt_log_print(LOG_CONNECTION_LISTEN, "failed to open listen port");
1128
1129 return false;
1130 }
1131diff --git a/src/net/listen.h b/src/net/listen.h
1132index b3c845aa..58c06c7e 100644
1133--- a/src/net/listen.h
1134+++ b/src/net/listen.h
1135@@ -37,8 +37,8 @@
1136 #ifndef LIBTORRENT_LISTEN_H
1137 #define LIBTORRENT_LISTEN_H
1138
1139-#include <inttypes.h>
1140-#include lt_tr1_functional
1141+#include <cinttypes>
1142+#include <functional>
1143 #include <rak/socket_address.h>
1144
1145 #include "socket_base.h"
1146diff --git a/src/net/protocol_buffer.h b/src/net/protocol_buffer.h
1147index b64d47ea..f9711ded 100644
1148--- a/src/net/protocol_buffer.h
1149+++ b/src/net/protocol_buffer.h
1150@@ -38,7 +38,7 @@
1151 #define LIBTORRENT_NET_PROTOCOL_BUFFER_H
1152
1153 #include <memory>
1154-#include <inttypes.h>
1155+#include <cinttypes>
1156 #include <netinet/in.h>
1157
1158 #include "torrent/exceptions.h"
1159diff --git a/src/net/socket_base.h b/src/net/socket_base.h
1160index 02c9497d..20ae1d9f 100644
1161--- a/src/net/socket_base.h
1162+++ b/src/net/socket_base.h
1163@@ -38,7 +38,7 @@
1164 #define LIBTORRENT_NET_SOCKET_BASE_H
1165
1166 #include <list>
1167-#include <inttypes.h>
1168+#include <cinttypes>
1169
1170 #include "torrent/event.h"
1171 #include "socket_fd.h"
1172diff --git a/src/net/socket_fd.cc b/src/net/socket_fd.cc
1173index f04059f6..c36ff4b9 100644
1174--- a/src/net/socket_fd.cc
1175+++ b/src/net/socket_fd.cc
1176@@ -210,6 +210,11 @@ SocketFd::bind(const rak::socket_address& sa, unsigned int length) {
1177 return !::bind(m_fd, sa.c_sockaddr(), length);
1178 }
1179
1180+bool
1181+SocketFd::bind_sa(const sockaddr* sa) {
1182+ return bind(*rak::socket_address::cast_from(sa));
1183+}
1184+
1185 bool
1186 SocketFd::connect(const rak::socket_address& sa) {
1187 check_valid();
1188@@ -222,6 +227,11 @@ SocketFd::connect(const rak::socket_address& sa) {
1189 return !::connect(m_fd, sa.c_sockaddr(), sa.length()) || errno == EINPROGRESS;
1190 }
1191
1192+bool
1193+SocketFd::connect_sa(const sockaddr* sa) {
1194+ return connect(*rak::socket_address::cast_from(sa));
1195+}
1196+
1197 bool
1198 SocketFd::getsockname(rak::socket_address *sa) {
1199 check_valid();
1200diff --git a/src/net/socket_fd.h b/src/net/socket_fd.h
1201index 2329b4e9..4db0087b 100644
1202--- a/src/net/socket_fd.h
1203+++ b/src/net/socket_fd.h
1204@@ -39,6 +39,8 @@
1205
1206 #include <unistd.h>
1207
1208+struct sockaddr;
1209+
1210 namespace rak {
1211 class socket_address;
1212 }
1213@@ -80,7 +82,11 @@ public:
1214
1215 bool bind(const rak::socket_address& sa);
1216 bool bind(const rak::socket_address& sa, unsigned int length);
1217+ bool bind_sa(const sockaddr* sa);
1218+
1219 bool connect(const rak::socket_address& sa);
1220+ bool connect_sa(const sockaddr* sa);
1221+
1222 bool getsockname(rak::socket_address* sa);
1223
1224 bool listen(int size);
1225diff --git a/src/net/socket_listen.cc b/src/net/socket_listen.cc
1226new file mode 100644
1227index 00000000..97f006e0
1228--- /dev/null
1229+++ b/src/net/socket_listen.cc
1230@@ -0,0 +1,137 @@
1231+#include "config.h"
1232+
1233+#include "socket_listen.h"
1234+
1235+#include <algorithm>
1236+
1237+#include "torrent/connection_manager.h"
1238+#include "torrent/exceptions.h"
1239+#include "torrent/utils/log.h"
1240+#include "torrent/utils/random.h"
1241+
1242+#define LT_LOG_SAP(log_fmt, sap, ...) \
1243+ lt_log_print(LOG_CONNECTION_LISTEN, "listen->%s: " log_fmt, sap_pretty_str(sap).c_str(), __VA_ARGS__);
1244+
1245+namespace torrent {
1246+
1247+socket_listen::socket_listen() : m_backlog(SOMAXCONN) {
1248+}
1249+
1250+void
1251+socket_listen::set_backlog(int backlog) {
1252+ if (backlog < 0 || backlog > SOMAXCONN)
1253+ throw internal_error("Could not set socket_listen backlog, out-of-range value.");
1254+
1255+ m_backlog = backlog;
1256+}
1257+
1258+bool
1259+socket_listen::open(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, uint16_t start_port, fd_flags open_flags) {
1260+ if (is_open())
1261+ throw internal_error("socket_listen::open: already open");
1262+
1263+ if (!(sap_is_inet(sap) || sap_is_inet6(sap)) || sap_is_v4mapped(sap) || !sap_is_port_any(sap) || sap_is_broadcast(sap))
1264+ throw internal_error("socket_listen::open: socket address must be inet/inet6 with no port, and not v4mapped nor broadcast: " + sap_pretty_str(sap));
1265+
1266+ if (sap_is_inet(sap) && !(open_flags & fd_flag_v4only))
1267+ throw internal_error("socket_listen::open: socket address is inet without v4only flag");
1268+
1269+ if (first_port == 0 || last_port == 0 || start_port == 0 ||
1270+ !(first_port <= last_port && first_port <= start_port && start_port <= last_port))
1271+ throw internal_error("socket_listen::open: port range not valid");
1272+
1273+ int fd = fd_open(open_flags);
1274+
1275+ if (fd == -1) {
1276+ LT_LOG_SAP("open failed (flags:0x%x errno:%i message:'%s')", sap, open_flags, errno, std::strerror(errno));
1277+ return false;
1278+ }
1279+
1280+ uint16_t p = start_port;
1281+
1282+ do {
1283+ if (m_open_port(fd, sap, p))
1284+ return is_open();
1285+
1286+ if (p == last_port)
1287+ p = first_port;
1288+ else
1289+ p++;
1290+ } while (p != start_port);
1291+
1292+ LT_LOG_SAP("listen ports exhausted (fd:%i first_port:%" PRIu16 " last_port:%" PRIu16 ")",
1293+ sap, fd, first_port, last_port);
1294+ fd_close(fd);
1295+ return false;
1296+}
1297+
1298+bool
1299+socket_listen::open_randomize(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags) {
1300+ if (last_port < first_port)
1301+ throw internal_error("socket_listen::open_randomize: port range not valid");
1302+
1303+ return open(std::move(sap), first_port, last_port, random_uniform_uint16(first_port, last_port), open_flags);
1304+}
1305+
1306+bool
1307+socket_listen::open_sequential(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags) {
1308+ return open(std::move(sap), first_port, last_port, first_port, open_flags);
1309+}
1310+
1311+void
1312+socket_listen::close() {
1313+ if (!is_open())
1314+ return;
1315+
1316+ torrent::poll_event_closed(this);
1317+
1318+ fd_close(file_descriptor());
1319+ set_file_descriptor(-1);
1320+ m_socket_address.reset();
1321+}
1322+
1323+void
1324+socket_listen::event_read() {
1325+}
1326+
1327+void
1328+socket_listen::event_error() {
1329+}
1330+
1331+// Returns true if open is successful or if we cannot bind to the
1332+// address, returns false if other ports can be used.
1333+bool
1334+socket_listen::m_open_port(int fd, sa_unique_ptr& sap, uint16_t port) {
1335+ sap_set_port(sap, port);
1336+
1337+ if (!fd_bind(fd, sap.get())) {
1338+ if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
1339+ LT_LOG_SAP("listen address not usable (fd:%i errno:%i message:'%s')",
1340+ sap, fd, errno, std::strerror(errno));
1341+ fd_close(fd);
1342+ return true;
1343+ }
1344+
1345+ return false;
1346+ }
1347+
1348+ if (!fd_listen(fd, m_backlog)) {
1349+ LT_LOG_SAP("call to listen failed (fd:%i backlog:%i errno:%i message:'%s')",
1350+ sap, fd, m_backlog, errno, std::strerror(errno));
1351+ fd_close(fd);
1352+ return true;
1353+ }
1354+
1355+ LT_LOG_SAP("open listen port success (fd:%i backlog:%i)", sap, fd, m_backlog);
1356+
1357+ m_fileDesc = fd;
1358+ m_socket_address.swap(sap);
1359+
1360+ torrent::poll_event_open(this);
1361+ torrent::poll_event_insert_read(this);
1362+ torrent::poll_event_insert_error(this);
1363+
1364+ return true;
1365+}
1366+
1367+}
1368diff --git a/src/net/socket_listen.h b/src/net/socket_listen.h
1369new file mode 100644
1370index 00000000..817d5fa5
1371--- /dev/null
1372+++ b/src/net/socket_listen.h
1373@@ -0,0 +1,46 @@
1374+#ifndef LIBTORRENT_SOCKET_LISTEN_H
1375+#define LIBTORRENT_SOCKET_LISTEN_H
1376+
1377+#include <cinttypes>
1378+#include <functional>
1379+
1380+#include "torrent/net/fd.h"
1381+#include "torrent/net/socket_address.h"
1382+#include "torrent/net/socket_event.h"
1383+
1384+namespace torrent {
1385+
1386+class socket_listen : public socket_event {
1387+public:
1388+ typedef std::function<void (int, sa_unique_ptr)> accepted_ftor;
1389+
1390+ socket_listen();
1391+
1392+ int backlog() const;
1393+
1394+ void set_backlog(int backlog);
1395+ void set_slot_accepted(accepted_ftor&& ftor);
1396+
1397+ bool open(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, uint16_t start_port, fd_flags open_flags);
1398+ bool open_randomize(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags);
1399+ bool open_sequential(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags);
1400+ void close();
1401+
1402+ void event_read() override;
1403+ void event_error() override;
1404+
1405+ const char* type_name() const override { return "socket_listen"; }
1406+
1407+private:
1408+ bool m_open_port(int fd, sa_unique_ptr& sap, uint16_t port);
1409+
1410+ int m_backlog;
1411+ accepted_ftor m_slot_accepted;
1412+};
1413+
1414+inline int socket_listen::backlog() const { return m_backlog; }
1415+inline void socket_listen::set_slot_accepted(accepted_ftor&& ftor) { m_slot_accepted = ftor; }
1416+
1417+}
1418+
1419+#endif
1420diff --git a/src/net/socket_set.h b/src/net/socket_set.h
1421index 9264edf7..78443c88 100644
1422--- a/src/net/socket_set.h
1423+++ b/src/net/socket_set.h
1424@@ -39,7 +39,7 @@
1425
1426 #include <list>
1427 #include <vector>
1428-#include <inttypes.h>
1429+#include <cinttypes>
1430 #include <rak/allocators.h>
1431
1432 #include "torrent/exceptions.h"
1433diff --git a/src/net/throttle_node.h b/src/net/throttle_node.h
1434index 77cb6cc7..5af27a22 100644
1435--- a/src/net/throttle_node.h
1436+++ b/src/net/throttle_node.h
1437@@ -37,7 +37,7 @@
1438 #ifndef LIBTORRENT_NET_THROTTLE_NODE_H
1439 #define LIBTORRENT_NET_THROTTLE_NODE_H
1440
1441-#include lt_tr1_functional
1442+#include <functional>
1443
1444 #include "torrent/rate.h"
1445
1446diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc
1447index 6b41bbe3..1b877c7a 100644
1448--- a/src/protocol/handshake.cc
1449+++ b/src/protocol/handshake.cc
1450@@ -46,6 +46,7 @@
1451 #include "torrent/error.h"
1452 #include "torrent/poll.h"
1453 #include "torrent/throttle.h"
1454+#include "torrent/utils/log.h"
1455 #include "utils/diffie_hellman.h"
1456
1457 #include "globals.h"
1458@@ -55,6 +56,10 @@
1459 #include "handshake.h"
1460 #include "handshake_manager.h"
1461
1462+#define LT_LOG(log_fmt, ...) \
1463+ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake->%s: " log_fmt, \
1464+ m_address.pretty_address_str().c_str(), __VA_ARGS__);
1465+
1466 namespace torrent {
1467
1468 const char* Handshake::m_protocol = "BitTorrent protocol";
1469@@ -862,7 +867,7 @@ restart:
1470 m_manager->receive_failed(this, e.type(), e.error());
1471
1472 } catch (network_error& e) {
1473- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error);
1474+ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_read_error);
1475 }
1476 }
1477
1478@@ -969,7 +974,7 @@ Handshake::event_write() {
1479 m_manager->receive_failed(this, e.type(), e.error());
1480
1481 } catch (network_error& e) {
1482- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error);
1483+ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_write_error);
1484 }
1485 }
1486
1487@@ -1070,7 +1075,7 @@ Handshake::prepare_peer_info() {
1488 m_peerInfo = m_download->peer_list()->connected(m_address.c_sockaddr(), PeerList::connect_incoming);
1489
1490 if (m_peerInfo == NULL)
1491- throw handshake_error(ConnectionManager::handshake_failed, e_handshake_network_error);
1492+ throw handshake_error(ConnectionManager::handshake_failed, e_handshake_no_peer_info);
1493
1494 if (m_peerInfo->failed_counter() > m_manager->max_failed)
1495 throw handshake_error(ConnectionManager::handshake_dropped, e_handshake_toomanyfailed);
1496@@ -1221,7 +1226,7 @@ Handshake::event_error() {
1497 if (m_state == INACTIVE)
1498 throw internal_error("Handshake::event_error() called on an inactive handshake.");
1499
1500- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error);
1501+ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_socket_error);
1502 }
1503
1504 }
1505diff --git a/src/protocol/handshake_manager.cc b/src/protocol/handshake_manager.cc
1506index b52c8d4e..99592ba8 100644
1507--- a/src/protocol/handshake_manager.cc
1508+++ b/src/protocol/handshake_manager.cc
1509@@ -1,39 +1,3 @@
1510-// libTorrent - BitTorrent library
1511-// Copyright (C) 2005-2011, Jari Sundell
1512-//
1513-// This program is free software; you can redistribute it and/or modify
1514-// it under the terms of the GNU General Public License as published by
1515-// the Free Software Foundation; either version 2 of the License, or
1516-// (at your option) any later version.
1517-//
1518-// This program is distributed in the hope that it will be useful,
1519-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1520-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1521-// GNU General Public License for more details.
1522-//
1523-// You should have received a copy of the GNU General Public License
1524-// along with this program; if not, write to the Free Software
1525-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1526-//
1527-// In addition, as a special exception, the copyright holders give
1528-// permission to link the code of portions of this program with the
1529-// OpenSSL library under certain conditions as described in each
1530-// individual source file, and distribute linked combinations
1531-// including the two.
1532-//
1533-// You must obey the GNU General Public License in all respects for
1534-// all of the code used other than OpenSSL. If you modify file(s)
1535-// with this exception, you may extend this exception to your version
1536-// of the file(s), but you are not obligated to do so. If you do not
1537-// wish to do so, delete this exception statement from your version.
1538-// If you delete this exception statement from all source files in the
1539-// program, then also delete it here.
1540-//
1541-// Contact: Jari Sundell <jaris@ifi.uio.no>
1542-//
1543-// Skomakerveien 33
1544-// 3185 Skoppum, NORWAY
1545-
1546 #include "config.h"
1547
1548 #include <rak/socket_address.h>
1549@@ -54,10 +18,10 @@
1550
1551 #include "manager.h"
1552
1553-#define LT_LOG_SA(log_level, sa, log_fmt, ...) \
1554- lt_log_print(LOG_CONNECTION_##log_level, "handshake_manager->%s: " log_fmt, (sa)->address_str().c_str(), __VA_ARGS__);
1555-#define LT_LOG_SA_C(log_level, sa, log_fmt, ...) \
1556- lt_log_print(LOG_CONNECTION_##log_level, "handshake_manager->%s: " log_fmt, \
1557+#define LT_LOG_SA(sa, log_fmt, ...) \
1558+ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake_manager->%s: " log_fmt, (sa)->address_str().c_str(), __VA_ARGS__);
1559+#define LT_LOG_SA_C(sa, log_fmt, ...) \
1560+ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake_manager->%s: " log_fmt, \
1561 reinterpret_cast<const rak::socket_address*>(sa)->address_str().c_str(), __VA_ARGS__);
1562
1563 namespace torrent {
1564@@ -122,7 +86,7 @@ HandshakeManager::add_incoming(SocketFd fd, const rak::socket_address& sa) {
1565 return;
1566 }
1567
1568- LT_LOG_SA(INFO, &sa, "Adding incoming connection: fd:%i.", fd.get_fd());
1569+ LT_LOG_SA(&sa, "Adding incoming connection: fd:%i.", fd.get_fd());
1570
1571 manager->connection_manager()->inc_socket_count();
1572
1573@@ -183,7 +147,7 @@ HandshakeManager::create_outgoing(const rak::socket_address& sa, DownloadMain* d
1574 else
1575 message = ConnectionManager::handshake_outgoing;
1576
1577- LT_LOG_SA(INFO, &sa, "Adding outcoming connection: encryption:%x message:%x.", encryptionOptions, message);
1578+ LT_LOG_SA(&sa, "Adding outcoming connection: encryption:%x message:%x.", encryptionOptions, message);
1579 manager->connection_manager()->inc_socket_count();
1580
1581 Handshake* handshake = new Handshake(fd, this, encryptionOptions);
1582@@ -213,7 +177,7 @@ HandshakeManager::receive_succeeded(Handshake* handshake) {
1583 handshake->extensions())) != NULL) {
1584
1585 manager->client_list()->retrieve_id(&handshake->peer_info()->mutable_client_info(), handshake->peer_info()->id());
1586- LT_LOG_SA_C(INFO, handshake->peer_info()->socket_address(), "Handshake success.", 0);
1587+ LT_LOG_SA_C(handshake->peer_info()->socket_address(), "Handshake success.", 0);
1588
1589 pcb->peer_chunks()->set_have_timer(handshake->initialized_time());
1590
1591@@ -237,7 +201,7 @@ HandshakeManager::receive_succeeded(Handshake* handshake) {
1592 else
1593 reason = e_handshake_duplicate;
1594
1595- LT_LOG_SA_C(INFO, handshake->peer_info()->socket_address(), "Handshake dropped: %s.", strerror(reason));
1596+ LT_LOG_SA_C(handshake->peer_info()->socket_address(), "Handshake dropped: %s.", strerror(reason));
1597 handshake->destroy_connection();
1598 }
1599
1600@@ -255,13 +219,13 @@ HandshakeManager::receive_failed(Handshake* handshake, int message, int error) {
1601 handshake->deactivate_connection();
1602 handshake->destroy_connection();
1603
1604- LT_LOG_SA(INFO, sa, "Received error: message:%x %s.", message, strerror(error));
1605+ LT_LOG_SA(sa, "Received error: message:%x %s.", message, strerror(error));
1606
1607 if (handshake->encryption()->should_retry()) {
1608 int retry_options = handshake->retry_options() | ConnectionManager::encryption_retrying;
1609 DownloadMain* download = handshake->download();
1610
1611- LT_LOG_SA(INFO, sa, "Retrying %s.",
1612+ LT_LOG_SA(sa, "Retrying %s.",
1613 retry_options & ConnectionManager::encryption_try_outgoing ? "encrypted" : "plaintext");
1614
1615 create_outgoing(*sa, download, retry_options);
1616diff --git a/src/protocol/handshake_manager.h b/src/protocol/handshake_manager.h
1617index cfd52aa0..dc398e3e 100644
1618--- a/src/protocol/handshake_manager.h
1619+++ b/src/protocol/handshake_manager.h
1620@@ -1,45 +1,9 @@
1621-// libTorrent - BitTorrent library
1622-// Copyright (C) 2005-2011, Jari Sundell
1623-//
1624-// This program is free software; you can redistribute it and/or modify
1625-// it under the terms of the GNU General Public License as published by
1626-// the Free Software Foundation; either version 2 of the License, or
1627-// (at your option) any later version.
1628-//
1629-// This program is distributed in the hope that it will be useful,
1630-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1631-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1632-// GNU General Public License for more details.
1633-//
1634-// You should have received a copy of the GNU General Public License
1635-// along with this program; if not, write to the Free Software
1636-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1637-//
1638-// In addition, as a special exception, the copyright holders give
1639-// permission to link the code of portions of this program with the
1640-// OpenSSL library under certain conditions as described in each
1641-// individual source file, and distribute linked combinations
1642-// including the two.
1643-//
1644-// You must obey the GNU General Public License in all respects for
1645-// all of the code used other than OpenSSL. If you modify file(s)
1646-// with this exception, you may extend this exception to your version
1647-// of the file(s), but you are not obligated to do so. If you do not
1648-// wish to do so, delete this exception statement from your version.
1649-// If you delete this exception statement from all source files in the
1650-// program, then also delete it here.
1651-//
1652-// Contact: Jari Sundell <jaris@ifi.uio.no>
1653-//
1654-// Skomakerveien 33
1655-// 3185 Skoppum, NORWAY
1656-
1657 #ifndef LIBTORRENT_NET_HANDSHAKE_MANAGER_H
1658 #define LIBTORRENT_NET_HANDSHAKE_MANAGER_H
1659
1660-#include <string>
1661+#include <functional>
1662 #include <inttypes.h>
1663-#include lt_tr1_functional
1664+#include <string>
1665 #include <rak/functional.h>
1666 #include <rak/unordered_vector.h>
1667 #include <rak/socket_address.h>
1668diff --git a/src/protocol/peer_connection_base.cc b/src/protocol/peer_connection_base.cc
1669index c02998fb..bd870425 100644
1670--- a/src/protocol/peer_connection_base.cc
1671+++ b/src/protocol/peer_connection_base.cc
1672@@ -36,8 +36,6 @@
1673
1674 #include "config.h"
1675
1676-#define __STDC_FORMAT_MACROS
1677-
1678 #include <cstdio>
1679 #include <fcntl.h>
1680 #include <rak/error_number.h>
1681diff --git a/src/protocol/request_list.cc b/src/protocol/request_list.cc
1682index a4338bcb..ea5d388a 100644
1683--- a/src/protocol/request_list.cc
1684+++ b/src/protocol/request_list.cc
1685@@ -1,44 +1,8 @@
1686-// libTorrent - BitTorrent library
1687-// Copyright (C) 2005-2011, Jari Sundell
1688-//
1689-// This program is free software; you can redistribute it and/or modify
1690-// it under the terms of the GNU General Public License as published by
1691-// the Free Software Foundation; either version 2 of the License, or
1692-// (at your option) any later version.
1693-//
1694-// This program is distributed in the hope that it will be useful,
1695-// but WITHOUT ANY WARRANTY; without even the implied warranty of
1696-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1697-// GNU General Public License for more details.
1698-//
1699-// You should have received a copy of the GNU General Public License
1700-// along with this program; if not, write to the Free Software
1701-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1702-//
1703-// In addition, as a special exception, the copyright holders give
1704-// permission to link the code of portions of this program with the
1705-// OpenSSL library under certain conditions as described in each
1706-// individual source file, and distribute linked combinations
1707-// including the two.
1708-//
1709-// You must obey the GNU General Public License in all respects for
1710-// all of the code used other than OpenSSL. If you modify file(s)
1711-// with this exception, you may extend this exception to your version
1712-// of the file(s), but you are not obligated to do so. If you do not
1713-// wish to do so, delete this exception statement from your version.
1714-// If you delete this exception statement from all source files in the
1715-// program, then also delete it here.
1716-//
1717-// Contact: Jari Sundell <jaris@ifi.uio.no>
1718-//
1719-// Skomakerveien 33
1720-// 3185 Skoppum, NORWAY
1721-
1722 #include "config.h"
1723
1724 #include <algorithm>
1725 #include <functional>
1726-#include <inttypes.h>
1727+#include <cinttypes>
1728 #include <rak/functional.h>
1729
1730 #include "torrent/data/block.h"
1731diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am
1732index 1bdfde3d..8cd26ce7 100644
1733--- a/src/torrent/Makefile.am
1734+++ b/src/torrent/Makefile.am
1735@@ -22,6 +22,7 @@ libsub_torrent_la_SOURCES = \
1736 download_info.h \
1737 error.cc \
1738 error.h \
1739+ event.cc \
1740 event.h \
1741 exceptions.cc \
1742 exceptions.h \
1743diff --git a/src/torrent/common.h b/src/torrent/common.h
1744index 3363143d..42cc3246 100644
1745--- a/src/torrent/common.h
1746+++ b/src/torrent/common.h
1747@@ -37,10 +37,13 @@
1748 #ifndef LIBTORRENT_COMMON_H
1749 #define LIBTORRENT_COMMON_H
1750
1751-#include <inttypes.h>
1752+#include <cinttypes>
1753 #include <cstddef>
1754
1755 struct sockaddr;
1756+struct sockaddr_in;
1757+struct sockaddr_in6;
1758+struct sockaddr_un;
1759
1760 namespace torrent {
1761
1762diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h
1763index 2dcf2b37..cf43b0bf 100644
1764--- a/src/torrent/connection_manager.h
1765+++ b/src/torrent/connection_manager.h
1766@@ -39,13 +39,13 @@
1767 #ifndef LIBTORRENT_CONNECTION_MANAGER_H
1768 #define LIBTORRENT_CONNECTION_MANAGER_H
1769
1770+#include <functional>
1771 #include <list>
1772 #include <arpa/inet.h>
1773 #include <netinet/in.h>
1774 #include <netinet/in_systm.h>
1775 #include <netinet/ip.h>
1776 #include <sys/socket.h>
1777-#include lt_tr1_functional
1778 #include <torrent/common.h>
1779
1780 namespace torrent {
1781diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h
1782index 2b9c9412..fc212047 100644
1783--- a/src/torrent/data/download_data.h
1784+++ b/src/torrent/data/download_data.h
1785@@ -37,7 +37,7 @@
1786 #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H
1787 #define LIBTORRENT_DATA_DOWNLOAD_DATA_H
1788
1789-#include lt_tr1_functional
1790+#include <functional>
1791
1792 #include <torrent/common.h>
1793 #include <torrent/bitfield.h>
1794diff --git a/src/torrent/data/file_list.cc b/src/torrent/data/file_list.cc
1795index 4721bdbd..2e334fa8 100644
1796--- a/src/torrent/data/file_list.cc
1797+++ b/src/torrent/data/file_list.cc
1798@@ -36,8 +36,6 @@
1799
1800 #include "config.h"
1801
1802-#define __STDC_FORMAT_MACROS
1803-
1804 #include <algorithm>
1805 #include <cstring>
1806 #include <functional>
1807diff --git a/src/torrent/data/transfer_list.h b/src/torrent/data/transfer_list.h
1808index 0a359b5e..9813af12 100644
1809--- a/src/torrent/data/transfer_list.h
1810+++ b/src/torrent/data/transfer_list.h
1811@@ -37,9 +37,10 @@
1812 #ifndef LIBTORRENT_TRANSFER_LIST_H
1813 #define LIBTORRENT_TRANSFER_LIST_H
1814
1815+#include <functional>
1816 #include <vector>
1817+
1818 #include <torrent/common.h>
1819-#include lt_tr1_functional
1820
1821 namespace torrent {
1822
1823diff --git a/src/torrent/download.cc b/src/torrent/download.cc
1824index edddedfb..f72c9351 100644
1825--- a/src/torrent/download.cc
1826+++ b/src/torrent/download.cc
1827@@ -36,9 +36,7 @@
1828
1829 #include "config.h"
1830
1831-#define __STDC_FORMAT_MACROS
1832-
1833-#include <inttypes.h>
1834+#include <cinttypes>
1835
1836 #include "data/block.h"
1837 #include "data/block_list.h"
1838diff --git a/src/torrent/download/choke_group.cc b/src/torrent/download/choke_group.cc
1839index a1540fc1..d9b25a9c 100644
1840--- a/src/torrent/download/choke_group.cc
1841+++ b/src/torrent/download/choke_group.cc
1842@@ -37,7 +37,7 @@
1843 #include "config.h"
1844
1845 #include <algorithm>
1846-#include lt_tr1_functional
1847+#include <functional>
1848
1849 #include "choke_group.h"
1850 #include "choke_queue.h"
1851diff --git a/src/torrent/download/choke_group.h b/src/torrent/download/choke_group.h
1852index 93fd1d02..50804b3e 100644
1853--- a/src/torrent/download/choke_group.h
1854+++ b/src/torrent/download/choke_group.h
1855@@ -39,7 +39,7 @@
1856
1857 #include <string>
1858 #include <vector>
1859-#include <inttypes.h>
1860+#include <cinttypes>
1861 #include <torrent/common.h>
1862 #include <torrent/download/choke_queue.h>
1863
1864diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc
1865index 3827e25e..7c00b686 100644
1866--- a/src/torrent/download/choke_queue.cc
1867+++ b/src/torrent/download/choke_queue.cc
1868@@ -37,10 +37,9 @@
1869 #include "config.h"
1870
1871 #include <algorithm>
1872+#include <cstdlib>
1873 #include <functional>
1874 #include <numeric>
1875-#include <cstdlib>
1876-#include lt_tr1_functional
1877 #include <rak/functional.h>
1878
1879 #include "protocol/peer_connection_base.h"
1880diff --git a/src/torrent/download/choke_queue.h b/src/torrent/download/choke_queue.h
1881index 973f6522..5e274a99 100644
1882--- a/src/torrent/download/choke_queue.h
1883+++ b/src/torrent/download/choke_queue.h
1884@@ -39,10 +39,11 @@
1885
1886 #include <torrent/common.h>
1887
1888+#include <cinttypes>
1889+#include <functional>
1890 #include <list>
1891 #include <vector>
1892-#include <inttypes.h>
1893-#include lt_tr1_functional
1894+
1895 #include <torrent/download/group_entry.h>
1896
1897 namespace torrent {
1898diff --git a/src/torrent/download/group_entry.h b/src/torrent/download/group_entry.h
1899index e167ecbb..a7c9e429 100644
1900--- a/src/torrent/download/group_entry.h
1901+++ b/src/torrent/download/group_entry.h
1902@@ -38,8 +38,9 @@
1903 #define LIBTORRENT_DOWNLOAD_GROUP_ENTRY_H
1904
1905 #include <algorithm>
1906+#include <functional>
1907 #include <vector>
1908-#include lt_tr1_functional
1909+
1910 #include <torrent/common.h>
1911 #include <torrent/exceptions.h>
1912
1913diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc
1914index bc6374d2..51434c91 100644
1915--- a/src/torrent/download/resource_manager.cc
1916+++ b/src/torrent/download/resource_manager.cc
1917@@ -38,7 +38,6 @@
1918
1919 #include <algorithm>
1920 #include <functional>
1921-#include lt_tr1_functional
1922 #include <limits>
1923 #include <numeric>
1924 #include <rak/functional.h>
1925diff --git a/src/torrent/download/resource_manager.h b/src/torrent/download/resource_manager.h
1926index b2f861af..ba61b45f 100644
1927--- a/src/torrent/download/resource_manager.h
1928+++ b/src/torrent/download/resource_manager.h
1929@@ -39,7 +39,7 @@
1930
1931 #include <string>
1932 #include <vector>
1933-#include <inttypes.h>
1934+#include <cinttypes>
1935 #include <torrent/common.h>
1936
1937 namespace torrent {
1938diff --git a/src/torrent/download_info.h b/src/torrent/download_info.h
1939index 341e4c25..2c4dbaf2 100644
1940--- a/src/torrent/download_info.h
1941+++ b/src/torrent/download_info.h
1942@@ -37,10 +37,10 @@
1943 #ifndef LIBTORRENT_DOWNLOAD_INFO_H
1944 #define LIBTORRENT_DOWNLOAD_INFO_H
1945
1946+#include <cinttypes>
1947+#include <functional>
1948 #include <list>
1949 #include <string>
1950-#include <inttypes.h>
1951-#include lt_tr1_functional
1952
1953 #include <torrent/rate.h>
1954 #include <torrent/hash_string.h>
1955diff --git a/src/torrent/error.cc b/src/torrent/error.cc
1956index 5010c803..eea9bb83 100644
1957--- a/src/torrent/error.cc
1958+++ b/src/torrent/error.cc
1959@@ -54,11 +54,15 @@ static const char* errorStrings[e_last + 1] = {
1960 "unencrypted connection rejected", // eh_unencrypted_rejected
1961 "invalid encryption method", // eh_invalid_encryption
1962 "encryption sync failed", // eh_encryption_sync_failed
1963- "network error", // eh_network_error
1964+ "<deprecated>", // eh_
1965 "network unreachable", // eh_network_unreachable
1966 "network timeout", // eh_network_timeout
1967 "invalid message order", // eh_invalid_order
1968 "too many failed chunks", // eh_toomanyfailed
1969+ "no peer info", // eh_no_peer_info
1970+ "network socket error", // eh_network_socket_error
1971+ "network read error", // eh_network_read_error
1972+ "network write error", // eh_network_write_error
1973
1974 // "", // e_handshake_incoming
1975 // "", // e_handshake_outgoing
1976diff --git a/src/torrent/error.h b/src/torrent/error.h
1977index f3fac463..295a595b 100644
1978--- a/src/torrent/error.h
1979+++ b/src/torrent/error.h
1980@@ -55,11 +55,14 @@ const int e_handshake_invalid_value = 8;
1981 const int e_handshake_unencrypted_rejected = 9;
1982 const int e_handshake_invalid_encryption = 10;
1983 const int e_handshake_encryption_sync_failed = 11;
1984-const int e_handshake_network_error = 12;
1985 const int e_handshake_network_unreachable = 13;
1986 const int e_handshake_network_timeout = 14;
1987 const int e_handshake_invalid_order = 15;
1988 const int e_handshake_toomanyfailed = 16;
1989+const int e_handshake_no_peer_info = 17;
1990+const int e_handshake_network_socket_error = 18;
1991+const int e_handshake_network_read_error = 19;
1992+const int e_handshake_network_write_error = 20;
1993
1994 // const int e_handshake_incoming = 13;
1995 // const int e_handshake_outgoing = 14;
1996@@ -69,7 +72,7 @@ const int e_handshake_toomanyfailed = 16;
1997 // const int e_handshake_retry_plaintext = 18;
1998 // const int e_handshake_retry_encrypted = 19;
1999
2000-const int e_last = 16;
2001+const int e_last = 20;
2002
2003 const char* strerror(int err) LIBTORRENT_EXPORT;
2004
2005diff --git a/src/torrent/event.cc b/src/torrent/event.cc
2006new file mode 100644
2007index 00000000..e68974ea
2008--- /dev/null
2009+++ b/src/torrent/event.cc
2010@@ -0,0 +1,19 @@
2011+#include "config.h"
2012+
2013+#include "event.h"
2014+
2015+#include "torrent/exceptions.h"
2016+#include "torrent/net/fd.h"
2017+
2018+namespace torrent {
2019+
2020+void
2021+Event::close_file_descriptor() {
2022+ if (!is_open())
2023+ throw internal_error("Tried to close already closed file descriptor on event type " + std::string(type_name()));
2024+
2025+ fd_close(m_fileDesc);
2026+ m_fileDesc = -1;
2027+}
2028+
2029+}
2030diff --git a/src/torrent/event.h b/src/torrent/event.h
2031index f3549762..73f87e46 100644
2032--- a/src/torrent/event.h
2033+++ b/src/torrent/event.h
2034@@ -1,39 +1,3 @@
2035-// libTorrent - BitTorrent library
2036-// Copyright (C) 2005-2011, Jari Sundell
2037-//
2038-// This program is free software; you can redistribute it and/or modify
2039-// it under the terms of the GNU General Public License as published by
2040-// the Free Software Foundation; either version 2 of the License, or
2041-// (at your option) any later version.
2042-//
2043-// This program is distributed in the hope that it will be useful,
2044-// but WITHOUT ANY WARRANTY; without even the implied warranty of
2045-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2046-// GNU General Public License for more details.
2047-//
2048-// You should have received a copy of the GNU General Public License
2049-// along with this program; if not, write to the Free Software
2050-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2051-//
2052-// In addition, as a special exception, the copyright holders give
2053-// permission to link the code of portions of this program with the
2054-// OpenSSL library under certain conditions as described in each
2055-// individual source file, and distribute linked combinations
2056-// including the two.
2057-//
2058-// You must obey the GNU General Public License in all respects for
2059-// all of the code used other than OpenSSL. If you modify file(s)
2060-// with this exception, you may extend this exception to your version
2061-// of the file(s), but you are not obligated to do so. If you do not
2062-// wish to do so, delete this exception statement from your version.
2063-// If you delete this exception statement from all source files in the
2064-// program, then also delete it here.
2065-//
2066-// Contact: Jari Sundell <jaris@ifi.uio.no>
2067-//
2068-// Skomakerveien 33
2069-// 3185 Skoppum, NORWAY
2070-
2071 #ifndef LIBTORRENT_TORRENT_EVENT_H
2072 #define LIBTORRENT_TORRENT_EVENT_H
2073
2074@@ -43,26 +7,48 @@ namespace torrent {
2075
2076 class LIBTORRENT_EXPORT Event {
2077 public:
2078- virtual ~Event() {}
2079+ Event();
2080+ virtual ~Event();
2081
2082- // These are not virtual as the fd is heavily used in select based
2083- // polling, thus fast access is critical to performance.
2084- int file_descriptor() const { return m_fileDesc; }
2085+ // TODO: Disable override.
2086+ bool is_open() const;
2087
2088- virtual void event_read() = 0;
2089- virtual void event_write() = 0;
2090- virtual void event_error() = 0;
2091+ int file_descriptor() const;
2092
2093- // Require all event types to define this function.
2094- virtual const char* type_name() const { return "default"; }
2095+ virtual void event_read() = 0;
2096+ virtual void event_write() = 0;
2097+ virtual void event_error() = 0;
2098
2099- // Event closed?
2100+ // TODO: Require all to define their ownh typename.
2101+ virtual const char* type_name() const { return "default"; }
2102
2103 protected:
2104- int m_fileDesc;
2105- bool m_ipv6_socket;
2106+ void close_file_descriptor();
2107+ void set_file_descriptor(int fd);
2108+
2109+ int m_fileDesc;
2110+
2111+ // TODO: Deprecate.
2112+ bool m_ipv6_socket;
2113 };
2114
2115+inline Event::Event() : m_fileDesc(-1), m_ipv6_socket(false) {}
2116+inline Event::~Event() {}
2117+inline bool Event::is_open() const { return file_descriptor() != -1; }
2118+inline int Event::file_descriptor() const { return m_fileDesc; }
2119+inline void Event::set_file_descriptor(int fd) { m_fileDesc = fd; }
2120+
2121+// Defined in 'src/globals.cc'.
2122+[[gnu::weak]] void poll_event_open(Event* event) LIBTORRENT_EXPORT;
2123+[[gnu::weak]] void poll_event_close(Event* event) LIBTORRENT_EXPORT;
2124+[[gnu::weak]] void poll_event_closed(Event* event) LIBTORRENT_EXPORT;
2125+[[gnu::weak]] void poll_event_insert_read(Event* event) LIBTORRENT_EXPORT;
2126+[[gnu::weak]] void poll_event_insert_write(Event* event) LIBTORRENT_EXPORT;
2127+[[gnu::weak]] void poll_event_insert_error(Event* event) LIBTORRENT_EXPORT;
2128+[[gnu::weak]] void poll_event_remove_read(Event* event) LIBTORRENT_EXPORT;
2129+[[gnu::weak]] void poll_event_remove_write(Event* event) LIBTORRENT_EXPORT;
2130+[[gnu::weak]] void poll_event_remove_error(Event* event) LIBTORRENT_EXPORT;
2131+
2132 }
2133
2134 #endif
2135diff --git a/src/torrent/http.h b/src/torrent/http.h
2136index c68d3933..c605afa5 100644
2137--- a/src/torrent/http.h
2138+++ b/src/torrent/http.h
2139@@ -38,9 +38,9 @@
2140 #define LIBTORRENT_HTTP_H
2141
2142 #include <string>
2143+#include <functional>
2144 #include <iosfwd>
2145 #include <list>
2146-#include lt_tr1_functional
2147 #include <torrent/common.h>
2148
2149 namespace torrent {
2150diff --git a/src/torrent/net/Makefile.am b/src/torrent/net/Makefile.am
2151index 51999d19..35dd4774 100644
2152--- a/src/torrent/net/Makefile.am
2153+++ b/src/torrent/net/Makefile.am
2154@@ -1,11 +1,25 @@
2155 noinst_LTLIBRARIES = libsub_torrentnet.la
2156
2157 libsub_torrentnet_la_SOURCES = \
2158+ address_info.cc \
2159+ address_info.h \
2160+ fd.cc \
2161+ fd.h \
2162+ socket_address.cc \
2163+ socket_address.h \
2164 socket_address_key.cc \
2165- socket_address_key.h
2166+ socket_address_key.h \
2167+ socket_event.cc \
2168+ socket_event.h \
2169+ types.h
2170
2171 AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
2172
2173 libtorrentincludedir = $(includedir)/torrent/net
2174 libtorrentinclude_HEADERS = \
2175- socket_address_key.h
2176+ address_info.h \
2177+ fd.h \
2178+ socket_address.h \
2179+ socket_address_key.h \
2180+ socket_event.h \
2181+ types.h
2182diff --git a/src/torrent/net/address_info.cc b/src/torrent/net/address_info.cc
2183new file mode 100644
2184index 00000000..25a51ebd
2185--- /dev/null
2186+++ b/src/torrent/net/address_info.cc
2187@@ -0,0 +1,43 @@
2188+#include "config.h"
2189+
2190+#include "address_info.h"
2191+
2192+namespace torrent {
2193+
2194+int
2195+ai_get_addrinfo(const char* nodename, const char* servname, const addrinfo* hints, ai_unique_ptr& res) {
2196+ addrinfo* ai;
2197+ int err = ::getaddrinfo(nodename, servname, hints, &ai);
2198+
2199+ if (err != 0)
2200+ return err;
2201+
2202+ res.reset(ai);
2203+ return 0;
2204+}
2205+
2206+sa_unique_ptr
2207+ai_get_first_sa(const char* nodename, const char* servname, const addrinfo* hints) {
2208+ ai_unique_ptr aip;
2209+
2210+ if (ai_get_addrinfo(nodename, servname, hints, aip) != 0)
2211+ return nullptr;
2212+
2213+ return sa_copy(aip->ai_addr);
2214+}
2215+
2216+int
2217+ai_each_inet_inet6_first(const char* nodename, ai_sockaddr_func lambda) {
2218+ int err;
2219+ ai_unique_ptr ai;
2220+
2221+ // TODO: Change to a single call using hints with both inet/inet6.
2222+ if ((err = ai_get_addrinfo(nodename, NULL, ai_make_hint(0, PF_INET, SOCK_STREAM).get(), ai)) != 0 &&
2223+ (err = ai_get_addrinfo(nodename, NULL, ai_make_hint(0, PF_INET6, SOCK_STREAM).get(), ai)) != 0)
2224+ return err;
2225+
2226+ lambda(ai->ai_addr);
2227+ return 0;
2228+}
2229+
2230+}
2231diff --git a/src/torrent/net/address_info.h b/src/torrent/net/address_info.h
2232new file mode 100644
2233index 00000000..c0b1c082
2234--- /dev/null
2235+++ b/src/torrent/net/address_info.h
2236@@ -0,0 +1,69 @@
2237+#ifndef LIBTORRENT_NET_ADDRESS_INFO_H
2238+#define LIBTORRENT_NET_ADDRESS_INFO_H
2239+
2240+#include <cstring>
2241+#include <functional>
2242+#include <memory>
2243+#include <string>
2244+#include <netdb.h>
2245+#include <torrent/common.h>
2246+#include <torrent/net/socket_address.h>
2247+
2248+namespace torrent {
2249+
2250+struct ai_deleter {
2251+ void operator()(addrinfo* ai) const { freeaddrinfo(ai); }
2252+};
2253+
2254+typedef std::unique_ptr<addrinfo, ai_deleter> ai_unique_ptr;
2255+typedef std::unique_ptr<const addrinfo, ai_deleter> c_ai_unique_ptr;
2256+typedef std::function<void (const sockaddr*)> ai_sockaddr_func;
2257+
2258+inline void ai_clear(addrinfo* ai);
2259+inline ai_unique_ptr ai_make_hint(int flags, int family, int socktype);
2260+
2261+int ai_get_addrinfo(const char* nodename, const char* servname, const addrinfo* hints, ai_unique_ptr& res) LIBTORRENT_EXPORT;
2262+
2263+// Helper functions:
2264+
2265+// TODO: Consider servname "0".
2266+// TODO: ai_get_first_sa_err that returns a tuple?
2267+sa_unique_ptr ai_get_first_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) LIBTORRENT_EXPORT;
2268+
2269+int ai_each_inet_inet6_first(const char* nodename, ai_sockaddr_func lambda) LIBTORRENT_EXPORT;
2270+
2271+// Get all addrinfo's, iterate, etc.
2272+
2273+//
2274+// Safe conversion from unique_ptr arguments:
2275+//
2276+
2277+inline void aip_clear(ai_unique_ptr& aip) { return ai_clear(aip.get()); }
2278+
2279+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); }
2280+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); }
2281+
2282+//
2283+// Implementations:
2284+//
2285+
2286+inline void
2287+ai_clear(addrinfo* ai) {
2288+ std::memset(ai, 0, sizeof(addrinfo));
2289+}
2290+
2291+inline ai_unique_ptr
2292+ai_make_hint(int flags, int family, int socktype) {
2293+ ai_unique_ptr aip(new addrinfo);
2294+
2295+ aip_clear(aip);
2296+ aip->ai_flags = flags;
2297+ aip->ai_family = family;
2298+ aip->ai_socktype = socktype;
2299+
2300+ return aip;
2301+}
2302+
2303+}
2304+
2305+#endif
2306diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc
2307new file mode 100644
2308index 00000000..07c91779
2309--- /dev/null
2310+++ b/src/torrent/net/fd.cc
2311@@ -0,0 +1,209 @@
2312+#include "config.h"
2313+
2314+#include "fd.h"
2315+
2316+#include <cerrno>
2317+#include <fcntl.h>
2318+#include <unistd.h>
2319+#include <netinet/in.h>
2320+#include <netinet/in_systm.h>
2321+#include <netinet/ip.h>
2322+
2323+#include "torrent/exceptions.h"
2324+#include "torrent/net/socket_address.h"
2325+#include "torrent/utils/log.h"
2326+
2327+#define LT_LOG(log_fmt, ...) \
2328+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt, __VA_ARGS__);
2329+#define LT_LOG_FLAG(log_fmt) \
2330+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (flags:0x%x)", flags);
2331+#define LT_LOG_FLAG_ERROR(log_fmt) \
2332+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (flags:0x%x errno:%i message:'%s')", \
2333+ flags, errno, std::strerror(errno));
2334+#define LT_LOG_FD(log_fmt) \
2335+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd);
2336+#define LT_LOG_FD_ERROR(log_fmt) \
2337+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \
2338+ fd, errno, std::strerror(errno));
2339+#define LT_LOG_FD_SOCKADDR(log_fmt) \
2340+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \
2341+ fd, sa_pretty_str(sa).c_str());
2342+#define LT_LOG_FD_SOCKADDR_ERROR(log_fmt) \
2343+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s errno:%i message:'%s')", \
2344+ fd, sa_pretty_str(sa).c_str(), errno, std::strerror(errno));
2345+#define LT_LOG_FD_FLAG(log_fmt) \
2346+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (flags:0x%x)", fd, flags);
2347+#define LT_LOG_FD_FLAG_ERROR(log_fmt) \
2348+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (flags:0x%x errno:%i message:'%s')", \
2349+ fd, flags, errno, std::strerror(errno));
2350+#define LT_LOG_FD_VALUE(log_fmt, value) \
2351+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (value:%i)", fd, (int)value);
2352+#define LT_LOG_FD_VALUE_ERROR(log_fmt, value) \
2353+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (value:%i errno:%i message:'%s')", \
2354+ fd, (int)value, errno, std::strerror(errno));
2355+
2356+namespace torrent {
2357+
2358+int fd__accept(int socket, sockaddr *address, socklen_t *address_len) { return ::accept(socket, address, address_len); }
2359+int fd__bind(int socket, const sockaddr *address, socklen_t address_len) { return ::bind(socket, address, address_len); }
2360+int fd__close(int fildes) { return ::close(fildes); }
2361+int fd__connect(int socket, const sockaddr *address, socklen_t address_len) { return ::connect(socket, address, address_len); }
2362+int fd__fcntl_int(int fildes, int cmd, int arg) { return ::fcntl(fildes, cmd, arg); }
2363+int fd__listen(int socket, int backlog) { return ::listen(socket, backlog); }
2364+int fd__setsockopt_int(int socket, int level, int option_name, int option_value) { return ::setsockopt(socket, level, option_name, &option_value, sizeof(int)); }
2365+int fd__socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); }
2366+
2367+int
2368+fd_open(fd_flags flags) {
2369+ int domain;
2370+ int protocol;
2371+
2372+ if (!fd_valid_flags(flags))
2373+ throw internal_error("torrent::fd_open failed: invalid fd_flags");
2374+
2375+ if ((flags & fd_flag_stream)) {
2376+ domain = SOCK_STREAM;
2377+ protocol = IPPROTO_TCP;
2378+ } else {
2379+ LT_LOG_FLAG("fd_open missing socket type");
2380+ errno = EINVAL;
2381+ return -1;
2382+ }
2383+
2384+ int fd = -1;
2385+
2386+ if (fd == -1 && !(flags & fd_flag_v4only)) {
2387+ LT_LOG_FLAG("fd_open opening ipv6 socket");
2388+ fd = fd__socket(PF_INET6, domain, protocol);
2389+ }
2390+
2391+ if (fd == -1 && !(flags & fd_flag_v6only)) {
2392+ LT_LOG_FLAG("fd_open opening ipv4 socket");
2393+ fd = fd__socket(PF_INET, domain, protocol);
2394+ }
2395+
2396+ if (fd == -1) {
2397+ LT_LOG_FLAG_ERROR("fd_open failed to open socket");
2398+ return -1;
2399+ }
2400+
2401+ if ((flags & fd_flag_v6only) && !fd_set_v6only(fd, true)) {
2402+ LT_LOG_FD_FLAG_ERROR("fd_open failed to set v6only");
2403+ fd_close(fd);
2404+ return -1;
2405+ }
2406+
2407+ if ((flags & fd_flag_nonblock) && !fd_set_nonblock(fd)) {
2408+ LT_LOG_FD_FLAG_ERROR("fd_open failed to set nonblock");
2409+ fd_close(fd);
2410+ return -1;
2411+ }
2412+
2413+ if ((flags & fd_flag_reuse_address) && !fd_set_reuse_address(fd, true)) {
2414+ LT_LOG_FD_FLAG_ERROR("fd_open failed to set reuse_address");
2415+ fd_close(fd);
2416+ return -1;
2417+ }
2418+
2419+ LT_LOG_FD_FLAG("fd_open succeeded");
2420+ return fd;
2421+}
2422+
2423+void
2424+fd_close(int fd) {
2425+ if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
2426+ throw internal_error("torrent::fd_close: tried to close stdin/out/err");
2427+
2428+ if (fd__close(fd) == -1)
2429+ throw internal_error("torrent::fd_close: " + std::string(strerror(errno)));
2430+
2431+ LT_LOG_FD("fd_close succeeded");
2432+}
2433+
2434+fd_sap_tuple
2435+fd_accept(int fd) {
2436+ sa_unique_ptr sap = sa_make_inet6();
2437+ socklen_t socklen = sap_length(sap);
2438+
2439+ int accept_fd = fd__accept(fd, sap.get(), &socklen);
2440+
2441+ if (accept_fd == -1) {
2442+ LT_LOG_FD_ERROR("fd_accept failed");
2443+ return fd_sap_tuple{-1, nullptr};
2444+ }
2445+
2446+ return fd_sap_tuple{accept_fd, std::move(sap)};
2447+}
2448+
2449+bool
2450+fd_bind(int fd, const sockaddr* sa) {
2451+ if (fd__bind(fd, sa, sa_length(sa)) == -1) {
2452+ LT_LOG_FD_SOCKADDR_ERROR("fd_bind failed");
2453+ return false;
2454+ }
2455+
2456+ LT_LOG_FD_SOCKADDR("fd_bind succeeded");
2457+ return true;
2458+}
2459+
2460+bool
2461+fd_connect(int fd, const sockaddr* sa) {
2462+ if (fd__connect(fd, sa, sa_length(sa)) == 0) {
2463+ LT_LOG_FD_SOCKADDR("fd_connect succeeded");
2464+ return true;
2465+ }
2466+
2467+ if (errno == EINPROGRESS) {
2468+ LT_LOG_FD_SOCKADDR("fd_connect succeeded and in progress");
2469+ return true;
2470+ }
2471+
2472+ LT_LOG_FD_SOCKADDR_ERROR("fd_connect failed");
2473+ return false;
2474+}
2475+
2476+bool
2477+fd_listen(int fd, int backlog) {
2478+ if (fd__listen(fd, backlog) == -1) {
2479+ LT_LOG_FD_VALUE_ERROR("fd_listen failed", backlog);
2480+ return false;
2481+ }
2482+
2483+ LT_LOG_FD_VALUE("fd_listen succeeded", backlog);
2484+ return true;
2485+}
2486+
2487+bool
2488+fd_set_nonblock(int fd) {
2489+ if (fd__fcntl_int(fd, F_SETFL, O_NONBLOCK) == -1) {
2490+ LT_LOG_FD_ERROR("fd_set_nonblock failed");
2491+ return false;
2492+ }
2493+
2494+ LT_LOG_FD("fd_set_nonblock succeeded");
2495+ return true;
2496+}
2497+
2498+bool
2499+fd_set_reuse_address(int fd, bool state) {
2500+ if (fd__setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, state) == -1) {
2501+ LT_LOG_FD_VALUE_ERROR("fd_set_reuse_address failed", state);
2502+ return false;
2503+ }
2504+
2505+ LT_LOG_FD_VALUE("fd_set_reuse_address succeeded", state);
2506+ return true;
2507+}
2508+
2509+bool
2510+fd_set_v6only(int fd, bool state) {
2511+ if (fd__setsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, state) == -1) {
2512+ LT_LOG_FD_VALUE_ERROR("fd_set_v6only failed", state);
2513+ return false;
2514+ }
2515+
2516+ LT_LOG_FD_VALUE("fd_set_v6only succeeded", state);
2517+ return true;
2518+}
2519+
2520+}
2521diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h
2522new file mode 100644
2523index 00000000..a7094646
2524--- /dev/null
2525+++ b/src/torrent/net/fd.h
2526@@ -0,0 +1,63 @@
2527+#ifndef LIBTORRENT_NET_FD_H
2528+#define LIBTORRENT_NET_FD_H
2529+
2530+#include <string>
2531+#include <torrent/common.h>
2532+#include <torrent/net/types.h>
2533+
2534+namespace torrent {
2535+
2536+enum fd_flags : int {
2537+ fd_flag_stream = 0x1,
2538+ fd_flag_nonblock = 0x10,
2539+ fd_flag_reuse_address = 0x20,
2540+ fd_flag_v4only = 0x40,
2541+ fd_flag_v6only = 0x80,
2542+ fd_flag_all = 0xff,
2543+};
2544+
2545+constexpr bool fd_valid_flags(fd_flags flags);
2546+
2547+int fd_open(fd_flags flags) LIBTORRENT_EXPORT;
2548+void fd_close(int fd) LIBTORRENT_EXPORT;
2549+
2550+fd_sap_tuple fd_accept(int fd) LIBTORRENT_EXPORT;
2551+
2552+bool fd_bind(int fd, const sockaddr* sa) LIBTORRENT_EXPORT;
2553+bool fd_connect(int fd, const sockaddr* sa) LIBTORRENT_EXPORT;
2554+bool fd_listen(int fd, int backlog) LIBTORRENT_EXPORT;
2555+
2556+bool fd_set_nonblock(int fd) LIBTORRENT_EXPORT;
2557+bool fd_set_reuse_address(int fd, bool state) LIBTORRENT_EXPORT;
2558+bool fd_set_v6only(int fd, bool state) LIBTORRENT_EXPORT;
2559+
2560+[[gnu::weak]] int fd__accept(int socket, sockaddr *address, socklen_t *address_len) LIBTORRENT_EXPORT;
2561+[[gnu::weak]] int fd__bind(int socket, const sockaddr *address, socklen_t address_len) LIBTORRENT_EXPORT;
2562+[[gnu::weak]] int fd__close(int fildes) LIBTORRENT_EXPORT;
2563+[[gnu::weak]] int fd__connect(int socket, const sockaddr *address, socklen_t address_len) LIBTORRENT_EXPORT;
2564+[[gnu::weak]] int fd__fcntl_int(int fildes, int cmd, int arg) LIBTORRENT_EXPORT;
2565+[[gnu::weak]] int fd__listen(int socket, int backlog) LIBTORRENT_EXPORT;
2566+[[gnu::weak]] int fd__setsockopt_int(int socket, int level, int option_name, int option_value) LIBTORRENT_EXPORT;
2567+[[gnu::weak]] int fd__socket(int domain, int type, int protocol) LIBTORRENT_EXPORT;
2568+
2569+constexpr fd_flags
2570+operator |(fd_flags lhs, fd_flags rhs) {
2571+ return static_cast<fd_flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
2572+}
2573+
2574+inline fd_flags&
2575+operator |=(fd_flags& lhs, fd_flags rhs) {
2576+ return (lhs = lhs | rhs);
2577+}
2578+
2579+constexpr bool
2580+fd_valid_flags(fd_flags flags) {
2581+ return
2582+ (flags & fd_flag_stream) &&
2583+ !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) &&
2584+ !(flags & ~(fd_flag_all));
2585+}
2586+
2587+}
2588+
2589+#endif
2590diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc
2591new file mode 100644
2592index 00000000..c36ba0ae
2593--- /dev/null
2594+++ b/src/torrent/net/socket_address.cc
2595@@ -0,0 +1,559 @@
2596+#include "config.h"
2597+
2598+#include "socket_address.h"
2599+
2600+#include <cstring>
2601+#include <arpa/inet.h>
2602+#include <sys/un.h>
2603+
2604+// TODO: Deprecate.
2605+#include "rak/socket_address.h"
2606+
2607+#include "torrent/exceptions.h"
2608+
2609+namespace torrent {
2610+
2611+constexpr uint32_t
2612+sin6_addr32_index(const sockaddr_in6* sa, unsigned int index) {
2613+ return
2614+ (sa->sin6_addr.s6_addr[index * 4 + 0] << 24) +
2615+ (sa->sin6_addr.s6_addr[index * 4 + 1] << 16) +
2616+ (sa->sin6_addr.s6_addr[index * 4 + 2] << 8) +
2617+ (sa->sin6_addr.s6_addr[index * 4 + 3] << 0);
2618+}
2619+
2620+inline void
2621+sin6_addr32_set(sockaddr_in6* sa, unsigned int index, uint32_t value) {
2622+ sa->sin6_addr.s6_addr[index * 4 + 0] = (value >> 24);
2623+ sa->sin6_addr.s6_addr[index * 4 + 1] = (value >> 16);
2624+ sa->sin6_addr.s6_addr[index * 4 + 2] = (value >> 8);
2625+ sa->sin6_addr.s6_addr[index * 4 + 3] = (value >> 0);
2626+}
2627+
2628+inline in6_addr
2629+sin6_make_addr32(uint32_t addr0, uint32_t addr1, uint32_t addr2, uint32_t addr3) {
2630+ uint32_t addr32[4];
2631+ addr32[0] = htonl(addr0);
2632+ addr32[1] = htonl(addr1);
2633+ addr32[2] = htonl(addr2);
2634+ addr32[3] = htonl(addr3);
2635+
2636+ return *reinterpret_cast<in6_addr*>(addr32);
2637+}
2638+
2639+bool
2640+sa_is_unspec(const sockaddr* sa) {
2641+ return sa != NULL && sa->sa_family == AF_UNSPEC;
2642+}
2643+
2644+bool
2645+sa_is_inet(const sockaddr* sa) {
2646+ return sa != NULL && sa->sa_family == AF_INET;
2647+}
2648+
2649+bool
2650+sa_is_inet6(const sockaddr* sa) {
2651+ return sa != NULL && sa->sa_family == AF_INET6;
2652+}
2653+
2654+bool
2655+sa_is_inet_inet6(const sockaddr* sa) {
2656+ return sa != NULL && (sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
2657+}
2658+
2659+bool
2660+sa_is_any(const sockaddr* sa) {
2661+ switch (sa->sa_family) {
2662+ case AF_INET:
2663+ return sin_is_any(reinterpret_cast<const sockaddr_in*>(sa));
2664+ case AF_INET6:
2665+ if (sa_is_v4mapped(sa))
2666+ return sin6_addr32_index(reinterpret_cast<const sockaddr_in6*>(sa), 3) == htonl(INADDR_ANY);
2667+ return sin6_is_any(reinterpret_cast<const sockaddr_in6*>(sa));
2668+ default:
2669+ return true;
2670+ }
2671+}
2672+
2673+bool
2674+sin_is_any(const sockaddr_in* sa) {
2675+ return sa->sin_addr.s_addr == htonl(INADDR_ANY);
2676+}
2677+
2678+bool
2679+sin6_is_any(const sockaddr_in6* sa) {
2680+ return std::memcmp(&sa->sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0;
2681+}
2682+
2683+bool
2684+sa_is_broadcast(const sockaddr* sa) {
2685+ switch (sa->sa_family) {
2686+ case AF_INET:
2687+ return sin_is_broadcast(reinterpret_cast<const sockaddr_in*>(sa));
2688+ case AF_INET6:
2689+ if (sa_is_v4mapped(sa))
2690+ return sin6_addr32_index(reinterpret_cast<const sockaddr_in6*>(sa), 3) == htonl(INADDR_BROADCAST);
2691+ return false;
2692+ default:
2693+ return false;
2694+ }
2695+}
2696+
2697+bool
2698+sin_is_broadcast(const sockaddr_in* sa) {
2699+ return sa->sin_addr.s_addr == htonl(INADDR_BROADCAST);
2700+}
2701+
2702+bool
2703+sa_is_v4mapped(const sockaddr* sa) {
2704+ return sa != NULL && sa->sa_family == AF_INET6 && sin6_is_v4mapped(reinterpret_cast<const sockaddr_in6*>(sa));
2705+}
2706+
2707+bool
2708+sin6_is_v4mapped(const sockaddr_in6* sa) {
2709+ return sa != NULL && IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr);
2710+}
2711+
2712+bool
2713+sa_is_port_any(const sockaddr* sa) {
2714+ return sa_port(sa) == 0;
2715+}
2716+
2717+size_t
2718+sa_length(const sockaddr* sa) {
2719+ switch(sa->sa_family) {
2720+ case AF_INET:
2721+ return sizeof(sockaddr_in);
2722+ case AF_INET6:
2723+ return sizeof(sockaddr_in6);
2724+ default:
2725+ return sizeof(sa);
2726+ }
2727+}
2728+
2729+sa_unique_ptr
2730+sa_make_unspec() {
2731+ sa_unique_ptr sa(new sockaddr);
2732+
2733+ std::memset(sa.get(), 0, sizeof(sa));
2734+ sa.get()->sa_family = AF_UNSPEC;
2735+
2736+ return sa;
2737+}
2738+
2739+sa_unique_ptr
2740+sa_make_inet() {
2741+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sin_make().release()));
2742+}
2743+
2744+sa_unique_ptr
2745+sa_make_inet6() {
2746+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sin6_make().release()));
2747+}
2748+
2749+sa_unique_ptr
2750+sa_make_unix(const std::string& pathname) {
2751+ if (!pathname.empty())
2752+ throw internal_error("torrent::sa_make_unix: function not implemented");
2753+
2754+ sun_unique_ptr sunp(new sockaddr_un);
2755+
2756+ std::memset(sunp.get(), 0, sizeof(sockaddr_un));
2757+ sunp->sun_family = AF_UNIX;
2758+ // TODO: verify length, copy pathname
2759+
2760+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sunp.release()));
2761+}
2762+
2763+sa_unique_ptr
2764+sa_convert(const sockaddr* sa) {
2765+ if (sa == NULL)
2766+ return sa_make_unspec();
2767+
2768+ switch(sa->sa_family) {
2769+ case AF_INET:
2770+ return sa_copy_in(reinterpret_cast<const sockaddr_in*>(sa));
2771+ case AF_INET6:
2772+ if (sin6_is_v4mapped(reinterpret_cast<const sockaddr_in6*>(sa)))
2773+ return sa_from_v4mapped_in6(reinterpret_cast<const sockaddr_in6*>(sa));
2774+
2775+ return sa_copy_in6(reinterpret_cast<const sockaddr_in6*>(sa));
2776+ case AF_UNSPEC:
2777+ return sa_make_unspec();
2778+ default:
2779+ throw internal_error("torrent::sa_convert: sockaddr is not a valid family");
2780+ }
2781+}
2782+
2783+sa_unique_ptr
2784+sa_copy(const sockaddr* sa) {
2785+ if (sa == nullptr)
2786+ throw internal_error("torrent::sa_copy: sockaddr is a nullptr");
2787+
2788+ switch(sa->sa_family) {
2789+ case AF_INET:
2790+ return sa_copy_in(reinterpret_cast<const sockaddr_in*>(sa));
2791+ case AF_INET6:
2792+ return sa_copy_in6(reinterpret_cast<const sockaddr_in6*>(sa));
2793+ case AF_UNSPEC:
2794+ return sa_make_unspec();
2795+ default:
2796+ throw internal_error("torrent::sa_copy: sockaddr is not a valid family");
2797+ }
2798+}
2799+
2800+sa_unique_ptr
2801+sa_copy_in(const sockaddr_in* sa) {
2802+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in));
2803+ std::memcpy(result.get(), sa, sizeof(sockaddr_in));
2804+ return result;
2805+}
2806+
2807+sa_unique_ptr
2808+sa_copy_in6(const sockaddr_in6* sa) {
2809+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in6));
2810+ std::memcpy(result.get(), sa, sizeof(sockaddr_in6));
2811+ return result;
2812+}
2813+
2814+sa_unique_ptr
2815+sa_copy_addr(const sockaddr* sa, uint16_t port) {
2816+ if (sa == nullptr)
2817+ throw internal_error("torrent::sa_copy_addr: sockaddr is a nullptr");
2818+
2819+ switch(sa->sa_family) {
2820+ case AF_INET:
2821+ return sa_copy_addr_in(reinterpret_cast<const sockaddr_in*>(sa), port);
2822+ case AF_INET6:
2823+ return sa_copy_addr_in6(reinterpret_cast<const sockaddr_in6*>(sa), port);
2824+ case AF_UNSPEC:
2825+ return sa_make_unspec();
2826+ default:
2827+ throw internal_error("torrent::sa_copy_addr: sockaddr is not a valid family");
2828+ }
2829+}
2830+
2831+sa_unique_ptr
2832+sa_copy_addr_in(const sockaddr_in* sa, uint16_t port) {
2833+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in));
2834+ std::memset(result.get(), 0, sizeof(sockaddr_in));
2835+ reinterpret_cast<sockaddr_in*>(result.get())->sin_family = AF_INET;
2836+ reinterpret_cast<sockaddr_in*>(result.get())->sin_addr = sa->sin_addr;
2837+ reinterpret_cast<sockaddr_in*>(result.get())->sin_port = htons(port);
2838+ return result;
2839+}
2840+
2841+sa_unique_ptr
2842+sa_copy_addr_in6(const sockaddr_in6* sa, uint16_t port) {
2843+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in6));
2844+ std::memset(result.get(), 0, sizeof(sockaddr_in6));
2845+ reinterpret_cast<sockaddr_in6*>(result.get())->sin6_family = AF_INET6;
2846+ std::memcpy(&reinterpret_cast<sockaddr_in6*>(result.get())->sin6_addr, &sa->sin6_addr, sizeof(in6_addr));
2847+ reinterpret_cast<sockaddr_in6*>(result.get())->sin6_port = htons(port);
2848+ return result;
2849+}
2850+
2851+sin_unique_ptr
2852+sin_copy(const sockaddr_in* sa) {
2853+ sin_unique_ptr result(new sockaddr_in);
2854+ std::memcpy(result.get(), sa, sizeof(sockaddr_in));
2855+ return result;
2856+}
2857+
2858+sin6_unique_ptr
2859+sin6_copy(const sockaddr_in6* sa) {
2860+ sin6_unique_ptr result(new sockaddr_in6);
2861+ std::memcpy(result.get(), sa, sizeof(sockaddr_in6));
2862+ return result;
2863+}
2864+
2865+sin_unique_ptr
2866+sin_make() {
2867+ sin_unique_ptr sa(new sockaddr_in);
2868+ std::memset(sa.get(), 0, sizeof(sockaddr_in));
2869+ sa.get()->sin_family = AF_INET;
2870+
2871+ return sa;
2872+}
2873+
2874+sin6_unique_ptr
2875+sin6_make() {
2876+ sin6_unique_ptr sa(new sockaddr_in6);
2877+ std::memset(sa.get(), 0, sizeof(sockaddr_in6));
2878+ sa.get()->sin6_family = AF_INET6;
2879+
2880+ return sa;
2881+}
2882+
2883+sa_unique_ptr
2884+sa_from_v4mapped(const sockaddr* sa) {
2885+ if (!sa_is_inet6(sa))
2886+ throw internal_error("torrent::sa_from_v4mapped: sockaddr is not inet6");
2887+
2888+ return sa_from_in(sin_from_v4mapped_in6(reinterpret_cast<const sockaddr_in6*>(sa)));
2889+}
2890+
2891+sa_unique_ptr
2892+sa_to_v4mapped(const sockaddr* sa) {
2893+ if (!sa_is_inet(sa))
2894+ throw internal_error("torrent::sa_to_v4mapped: sockaddr is not inet");
2895+
2896+ return sa_from_in6(sin6_to_v4mapped_in(reinterpret_cast<const sockaddr_in*>(sa)));
2897+}
2898+
2899+sin_unique_ptr
2900+sin_from_v4mapped_in6(const sockaddr_in6* sin6) {
2901+ if (!sin6_is_v4mapped(sin6))
2902+ throw internal_error("torrent::sin6_is_v4mapped: sockaddr_in6 is not v4mapped");
2903+
2904+ sin_unique_ptr result = sin_make();
2905+ result.get()->sin_addr.s_addr = reinterpret_cast<in_addr_t>(htonl(sin6_addr32_index(sin6, 3)));
2906+ result.get()->sin_port = sin6->sin6_port;
2907+
2908+ return result;
2909+}
2910+
2911+sin6_unique_ptr
2912+sin6_to_v4mapped_in(const sockaddr_in* sin) {
2913+ sin6_unique_ptr result = sin6_make();
2914+
2915+ result.get()->sin6_addr = sin6_make_addr32(0, 0, 0xffff, ntohl(sin->sin_addr.s_addr));
2916+ result.get()->sin6_port = sin->sin_port;
2917+
2918+ return result;
2919+}
2920+
2921+sin_unique_ptr
2922+sin_from_sa(sa_unique_ptr&& sap) {
2923+ if (!sap_is_inet(sap))
2924+ throw internal_error("torrent::sin_from_sa: sockaddr is nullptr or not inet");
2925+
2926+ return sin_unique_ptr(reinterpret_cast<sockaddr_in*>(sap.release()));
2927+}
2928+
2929+sin6_unique_ptr
2930+sin6_from_sa(sa_unique_ptr&& sap) {
2931+ if (!sap_is_inet6(sap))
2932+ throw internal_error("torrent::sin6_from_sa: sockaddr is nullptr or not inet6");
2933+
2934+ return sin6_unique_ptr(reinterpret_cast<sockaddr_in6*>(sap.release()));
2935+}
2936+
2937+c_sin_unique_ptr
2938+sin_from_c_sa(c_sa_unique_ptr&& sap) {
2939+ if (!sap_is_inet(sap))
2940+ throw internal_error("torrent::sin_from_c_sa: sockaddr is nullptr or not inet");
2941+
2942+ return c_sin_unique_ptr(reinterpret_cast<const sockaddr_in*>(sap.release()));
2943+}
2944+
2945+c_sin6_unique_ptr
2946+sin6_from_c_sa(sa_unique_ptr&& sap) {
2947+ if (!sap_is_inet6(sap))
2948+ throw internal_error("torrent::sin6_from_c_sa: sockaddr is nullptr or not inet6");
2949+
2950+ return c_sin6_unique_ptr(reinterpret_cast<const sockaddr_in6*>(sap.release()));
2951+}
2952+
2953+void
2954+sa_clear_inet6(sockaddr_in6* sa) {
2955+ std::memset(sa, 0, sizeof(sockaddr_in6));
2956+ sa->sin6_family = AF_INET6;
2957+}
2958+
2959+uint16_t
2960+sa_port(const sockaddr* sa) {
2961+ if (sa == NULL)
2962+ return 0;
2963+
2964+ switch(sa->sa_family) {
2965+ case AF_INET:
2966+ return ntohs(reinterpret_cast<const sockaddr_in*>(sa)->sin_port);
2967+ case AF_INET6:
2968+ return ntohs(reinterpret_cast<const sockaddr_in6*>(sa)->sin6_port);
2969+ default:
2970+ return 0;
2971+ }
2972+}
2973+
2974+void
2975+sa_set_port(sockaddr* sa, uint16_t port) {
2976+ switch(sa->sa_family) {
2977+ case AF_INET:
2978+ reinterpret_cast<sockaddr_in*>(sa)->sin_port = htons(port);
2979+ return;
2980+ case AF_INET6:
2981+ reinterpret_cast<sockaddr_in6*>(sa)->sin6_port = htons(port);
2982+ return;
2983+ default:
2984+ throw internal_error("torrent::sa_set_port: invalid family type");
2985+ }
2986+}
2987+
2988+bool
2989+sa_equal(const sockaddr* lhs, const sockaddr* rhs) {
2990+ switch(rhs->sa_family) {
2991+ case AF_INET:
2992+ case AF_INET6:
2993+ case AF_UNSPEC:
2994+ break;
2995+ default:
2996+ throw internal_error("torrent::sa_equal: rhs sockaddr is not a valid family");
2997+ }
2998+
2999+ switch(lhs->sa_family) {
3000+ case AF_INET:
3001+ return lhs->sa_family == rhs->sa_family &&
3002+ sin_equal(reinterpret_cast<const sockaddr_in*>(lhs), reinterpret_cast<const sockaddr_in*>(rhs));
3003+ case AF_INET6:
3004+ return lhs->sa_family == rhs->sa_family &&
3005+ sin6_equal(reinterpret_cast<const sockaddr_in6*>(lhs), reinterpret_cast<const sockaddr_in6*>(rhs));
3006+ case AF_UNSPEC:
3007+ return lhs->sa_family == rhs->sa_family;
3008+ default:
3009+ throw internal_error("torrent::sa_equal: lhs sockaddr is not a valid family");
3010+ }
3011+}
3012+
3013+bool
3014+sin_equal(const sockaddr_in* lhs, const sockaddr_in* rhs) {
3015+ return lhs->sin_port == rhs->sin_port && lhs->sin_addr.s_addr == rhs->sin_addr.s_addr;
3016+}
3017+
3018+bool
3019+sin6_equal(const sockaddr_in6* lhs, const sockaddr_in6* rhs) {
3020+ 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);
3021+}
3022+
3023+bool
3024+sa_equal_addr(const sockaddr* lhs, const sockaddr* rhs) {
3025+ switch(rhs->sa_family) {
3026+ case AF_INET:
3027+ case AF_INET6:
3028+ case AF_UNSPEC:
3029+ break;
3030+ default:
3031+ throw internal_error("torrent::sa_equal_addr: rhs sockaddr is not a valid family");
3032+ }
3033+
3034+ switch(lhs->sa_family) {
3035+ case AF_INET:
3036+ return lhs->sa_family == rhs->sa_family &&
3037+ sin_equal_addr(reinterpret_cast<const sockaddr_in*>(lhs), reinterpret_cast<const sockaddr_in*>(rhs));
3038+ case AF_INET6:
3039+ return lhs->sa_family == rhs->sa_family &&
3040+ sin6_equal_addr(reinterpret_cast<const sockaddr_in6*>(lhs), reinterpret_cast<const sockaddr_in6*>(rhs));
3041+ case AF_UNSPEC:
3042+ return lhs->sa_family == rhs->sa_family;
3043+ default:
3044+ throw internal_error("torrent::sa_equal_addr: lhs sockaddr is not a valid family");
3045+ }
3046+}
3047+
3048+bool
3049+sin_equal_addr(const sockaddr_in* lhs, const sockaddr_in* rhs) {
3050+ return lhs->sin_addr.s_addr == rhs->sin_addr.s_addr;
3051+}
3052+
3053+bool
3054+sin6_equal_addr(const sockaddr_in6* lhs, const sockaddr_in6* rhs) {
3055+ return std::equal(lhs->sin6_addr.s6_addr, lhs->sin6_addr.s6_addr + 16, rhs->sin6_addr.s6_addr);
3056+}
3057+
3058+std::string
3059+sa_addr_str(const sockaddr* sa) {
3060+ if (sa == NULL)
3061+ return "unspec";
3062+
3063+ switch (sa->sa_family) {
3064+ case AF_INET:
3065+ return sin_addr_str(reinterpret_cast<const sockaddr_in*>(sa));
3066+ case AF_INET6:
3067+ return sin6_addr_str(reinterpret_cast<const sockaddr_in6*>(sa));
3068+ case AF_UNSPEC:
3069+ return "unspec";
3070+ default:
3071+ return "invalid";
3072+ }
3073+}
3074+
3075+std::string
3076+sin_addr_str(const sockaddr_in* sa) {
3077+ char buffer[INET_ADDRSTRLEN];
3078+
3079+ if (inet_ntop(AF_INET, &sa->sin_addr, buffer, INET_ADDRSTRLEN) == NULL)
3080+ return "inet_error";
3081+
3082+ return buffer;
3083+}
3084+
3085+
3086+std::string
3087+sin6_addr_str(const sockaddr_in6* sa) {
3088+ char buffer[INET6_ADDRSTRLEN];
3089+
3090+ if (inet_ntop(AF_INET6, &sa->sin6_addr, buffer, INET6_ADDRSTRLEN) == NULL)
3091+ return "inet6_error";
3092+
3093+ return buffer;
3094+}
3095+
3096+std::string
3097+sa_pretty_str(const sockaddr* sa) {
3098+ if (sa == nullptr)
3099+ return "nullptr";
3100+
3101+ switch (sa->sa_family) {
3102+ case AF_INET:
3103+ return sin_pretty_str(reinterpret_cast<const sockaddr_in*>(sa));
3104+ case AF_INET6:
3105+ return sin6_pretty_str(reinterpret_cast<const sockaddr_in6*>(sa));
3106+ case AF_UNSPEC:
3107+ return "unspec";
3108+ default:
3109+ return "invalid";
3110+ }
3111+}
3112+
3113+std::string
3114+sin_pretty_str(const sockaddr_in* sa) {
3115+ auto result = sin_addr_str(sa);
3116+
3117+ if (sa->sin_port != 0)
3118+ result += ':' + std::to_string(ntohs(sa->sin_port));
3119+
3120+ return result;
3121+}
3122+
3123+std::string
3124+sin6_pretty_str(const sockaddr_in6* sa) {
3125+ auto result = "[" + sin6_addr_str(sa) + "]";
3126+
3127+ if (sa->sin6_port != 0)
3128+ result += ':' + std::to_string(ntohs(sa->sin6_port));
3129+
3130+ return result;
3131+}
3132+
3133+// Deprecated:
3134+
3135+void
3136+sa_inet_mapped_inet6(const sockaddr_in* sa, sockaddr_in6* mapped) {
3137+ uint32_t addr32[4];
3138+ addr32[0] = 0;
3139+ addr32[1] = 0;
3140+ addr32[2] = htonl(0xffff);
3141+ addr32[3] = sa->sin_addr.s_addr;
3142+
3143+ sa_clear_inet6(mapped);
3144+
3145+ mapped->sin6_addr = *reinterpret_cast<in6_addr*>(addr32);
3146+ mapped->sin6_port = sa->sin_port;
3147+}
3148+
3149+std::string
3150+sa_pretty_address_str(const sockaddr* sa) {
3151+ return sa_pretty_str(sa);
3152+}
3153+
3154+}
3155diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h
3156new file mode 100644
3157index 00000000..f64aee68
3158--- /dev/null
3159+++ b/src/torrent/net/socket_address.h
3160@@ -0,0 +1,229 @@
3161+#ifndef LIBTORRENT_NET_SOCKET_ADDRESS_H
3162+#define LIBTORRENT_NET_SOCKET_ADDRESS_H
3163+
3164+#include <memory>
3165+#include <string>
3166+#include <netinet/in.h>
3167+#include <sys/socket.h>
3168+#include <torrent/common.h>
3169+#include <torrent/net/types.h>
3170+
3171+namespace torrent {
3172+
3173+bool sa_is_unspec(const sockaddr* sa) LIBTORRENT_EXPORT;
3174+bool sa_is_inet(const sockaddr* sa) LIBTORRENT_EXPORT;
3175+bool sa_is_inet6(const sockaddr* sa) LIBTORRENT_EXPORT;
3176+bool sa_is_inet_inet6(const sockaddr* sa) LIBTORRENT_EXPORT;
3177+
3178+bool sa_is_any(const sockaddr* sa) LIBTORRENT_EXPORT;
3179+bool sin_is_any(const sockaddr_in* sa) LIBTORRENT_EXPORT;
3180+bool sin6_is_any(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
3181+
3182+bool sa_is_broadcast(const sockaddr* sa) LIBTORRENT_EXPORT;
3183+bool sin_is_broadcast(const sockaddr_in* sa) LIBTORRENT_EXPORT;
3184+
3185+bool sa_is_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT;
3186+bool sin6_is_v4mapped(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
3187+
3188+bool sa_is_port_any(const sockaddr* sa) LIBTORRENT_EXPORT;
3189+
3190+size_t sa_length(const sockaddr* sa) LIBTORRENT_EXPORT;
3191+
3192+sa_unique_ptr sa_make_unspec() LIBTORRENT_EXPORT;
3193+sa_unique_ptr sa_make_inet() LIBTORRENT_EXPORT;
3194+sa_unique_ptr sa_make_inet6() LIBTORRENT_EXPORT;
3195+sa_unique_ptr sa_make_unix(const std::string& pathname) LIBTORRENT_EXPORT;
3196+
3197+sa_unique_ptr sa_convert(const sockaddr* sa) LIBTORRENT_EXPORT;
3198+
3199+sa_unique_ptr sa_copy(const sockaddr* sa) LIBTORRENT_EXPORT;
3200+sa_unique_ptr sa_copy_in(const sockaddr_in* sa) LIBTORRENT_EXPORT;
3201+sa_unique_ptr sa_copy_in6(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
3202+sa_unique_ptr sa_copy_addr(const sockaddr* sa, uint16_t port = 0) LIBTORRENT_EXPORT;
3203+sa_unique_ptr sa_copy_addr_in(const sockaddr_in* sa, uint16_t port = 0) LIBTORRENT_EXPORT;
3204+sa_unique_ptr sa_copy_addr_in6(const sockaddr_in6* sa, uint16_t port = 0) LIBTORRENT_EXPORT;
3205+sin_unique_ptr sin_copy(const sockaddr_in* sa) LIBTORRENT_EXPORT;
3206+sin6_unique_ptr sin6_copy(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
3207+
3208+sin_unique_ptr sin_make() LIBTORRENT_EXPORT;
3209+sin6_unique_ptr sin6_make() LIBTORRENT_EXPORT;
3210+
3211+sa_unique_ptr sa_from_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT;
3212+sa_unique_ptr sa_to_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT;
3213+sa_unique_ptr sa_from_v4mapped_in6(const sockaddr_in6* sin6) LIBTORRENT_EXPORT;
3214+sa_unique_ptr sa_to_v4mapped_in(const sockaddr_in* sin) LIBTORRENT_EXPORT;
3215+sin_unique_ptr sin_from_v4mapped_in6(const sockaddr_in6* sin6) LIBTORRENT_EXPORT;
3216+sin6_unique_ptr sin6_to_v4mapped_in(const sockaddr_in* sin) LIBTORRENT_EXPORT;
3217+
3218+sa_unique_ptr sa_from_in(sin_unique_ptr&& sinp) LIBTORRENT_EXPORT;
3219+c_sa_unique_ptr sa_from_in(c_sin_unique_ptr&& sinp) LIBTORRENT_EXPORT;
3220+sa_unique_ptr sa_from_in6(sin6_unique_ptr&& sin6p) LIBTORRENT_EXPORT;
3221+c_sa_unique_ptr sa_from_in6(c_sin6_unique_ptr&& sin6p) LIBTORRENT_EXPORT;
3222+sin_unique_ptr sin_from_sa(sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
3223+sin6_unique_ptr sin6_from_sa(sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
3224+c_sin_unique_ptr sin_from_c_sa(c_sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
3225+c_sin6_unique_ptr sin6_from_c_sa(c_sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
3226+
3227+void sa_clear_inet6(sockaddr_in6* sa) LIBTORRENT_EXPORT;
3228+
3229+uint16_t sa_port(const sockaddr* sa) LIBTORRENT_EXPORT;
3230+void sa_set_port(sockaddr* sa, uint16_t port) LIBTORRENT_EXPORT;
3231+
3232+bool sa_equal(const sockaddr* lhs, const sockaddr* rhs) LIBTORRENT_EXPORT;
3233+bool sin_equal(const sockaddr_in* lhs, const sockaddr_in* rhs) LIBTORRENT_EXPORT;
3234+bool sin6_equal(const sockaddr_in6* lhs, const sockaddr_in6* rhs) LIBTORRENT_EXPORT;
3235+
3236+bool sa_equal_addr(const sockaddr* lhs, const sockaddr* rhs) LIBTORRENT_EXPORT;
3237+bool sin_equal_addr(const sockaddr_in* lhs, const sockaddr_in* rhs) LIBTORRENT_EXPORT;
3238+bool sin6_equal_addr(const sockaddr_in6* lhs, const sockaddr_in6* rhs) LIBTORRENT_EXPORT;
3239+
3240+std::string sa_addr_str(const sockaddr* sa) LIBTORRENT_EXPORT;
3241+std::string sin_addr_str(const sockaddr_in* sa) LIBTORRENT_EXPORT;
3242+std::string sin6_addr_str(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
3243+
3244+std::string sa_pretty_str(const sockaddr* sa) LIBTORRENT_EXPORT;
3245+std::string sin_pretty_str(const sockaddr_in* sa) LIBTORRENT_EXPORT;
3246+std::string sin6_pretty_str(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
3247+
3248+// Rename/replace:
3249+void sa_inet_mapped_inet6(const sockaddr_in* sa, sockaddr_in6* mapped) LIBTORRENT_EXPORT;
3250+
3251+std::string sa_pretty_address_str(const sockaddr* sa) LIBTORRENT_EXPORT;
3252+
3253+//
3254+// Tuples:
3255+//
3256+
3257+bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_EXPORT;
3258+
3259+//
3260+// Safe conversion from unique_ptr arguments:
3261+//
3262+
3263+inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
3264+inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
3265+inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
3266+inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
3267+inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
3268+inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
3269+inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); }
3270+inline bool sap_is_inet_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); }
3271+
3272+inline bool sap_is_any(const sa_unique_ptr& sap) { return sa_is_any(sap.get()); }
3273+inline bool sap_is_any(const c_sa_unique_ptr& sap) { return sa_is_any(sap.get()); }
3274+inline bool sinp_is_any(const sin_unique_ptr& sinp) { return sin_is_any(sinp.get()); }
3275+inline bool sinp_is_any(const c_sin_unique_ptr& sinp) { return sin_is_any(sinp.get()); }
3276+inline bool sinp6_is_any(const sin6_unique_ptr& sin6p) { return sin6_is_any(sin6p.get()); }
3277+inline bool sinp6_is_any(const c_sin6_unique_ptr& sin6p) { return sin6_is_any(sin6p.get()); }
3278+
3279+inline bool sap_is_broadcast(const sa_unique_ptr& sap) { return sa_is_broadcast(sap.get()); }
3280+inline bool sap_is_broadcast(const c_sa_unique_ptr& sap) { return sa_is_broadcast(sap.get()); }
3281+inline bool sinp_is_broadcast(const sin_unique_ptr& sap) { return sin_is_broadcast(sap.get()); }
3282+inline bool sinp_is_broadcast(const c_sin_unique_ptr& sap) { return sin_is_broadcast(sap.get()); }
3283+
3284+inline bool sap_is_v4mapped(const sa_unique_ptr& sap) { return sa_is_v4mapped(sap.get()); }
3285+inline bool sap_is_v4mapped(const c_sa_unique_ptr& sap) { return sa_is_v4mapped(sap.get()); }
3286+inline bool sinp6_is_v4mapped(const sin6_unique_ptr& sin6p) { return sin6_is_v4mapped(sin6p.get()); }
3287+inline bool sinp6_is_v4mapped(const c_sin6_unique_ptr& sin6p) { return sin6_is_v4mapped(sin6p.get()); }
3288+
3289+inline bool sap_is_port_any(const sa_unique_ptr& sap) { return sa_is_port_any(sap.get()); }
3290+inline bool sap_is_port_any(const c_sa_unique_ptr& sap) { return sa_is_port_any(sap.get()); }
3291+
3292+inline size_t sap_length(const sa_unique_ptr& sap) { return sa_length(sap.get()); }
3293+inline size_t sap_length(const c_sa_unique_ptr& sap) { return sa_length(sap.get()); }
3294+
3295+inline sa_unique_ptr sap_copy(const sa_unique_ptr& sap) { return sa_copy(sap.get()); }
3296+inline sa_unique_ptr sap_copy(const c_sa_unique_ptr& sap) { return sa_copy(sap.get()); }
3297+inline sa_unique_ptr sap_copy_addr(const sa_unique_ptr& sap, uint16_t port = 0) { return sa_copy_addr(sap.get(), port); }
3298+inline sa_unique_ptr sap_copy_addr(const c_sa_unique_ptr& sap, uint16_t port = 0) { return sa_copy_addr(sap.get(), port); }
3299+inline sa_unique_ptr sap_copy_in(const sin_unique_ptr& sinp) { return sa_copy_in(sinp.get()); }
3300+inline sa_unique_ptr sap_copy_in(const c_sin_unique_ptr& sinp) { return sa_copy_in(sinp.get()); }
3301+inline sa_unique_ptr sap_copy_in6(const sin6_unique_ptr& sin6p) { return sa_copy_in6(sin6p.get()); }
3302+inline sa_unique_ptr sap_copy_in6(const c_sin6_unique_ptr& sin6p) { return sa_copy_in6(sin6p.get()); }
3303+
3304+inline sa_unique_ptr sap_from_v4mapped(const sa_unique_ptr& sap) { return sa_from_v4mapped(sap.get()); }
3305+inline sa_unique_ptr sap_from_v4mapped(const c_sa_unique_ptr& sap) { return sa_from_v4mapped(sap.get()); }
3306+inline sa_unique_ptr sap_to_v4mapped(const sa_unique_ptr& sap) { return sa_to_v4mapped(sap.get()); }
3307+inline sa_unique_ptr sap_to_v4mapped(const c_sa_unique_ptr& sap) { return sa_to_v4mapped(sap.get()); }
3308+inline sin_unique_ptr sinp_from_v4mapped_in6(const sin6_unique_ptr& sin6p) { return sin_from_v4mapped_in6(sin6p.get()); }
3309+inline sin_unique_ptr sinp_from_v4mapped_in6(const c_sin6_unique_ptr& sin6p) { return sin_from_v4mapped_in6(sin6p.get()); }
3310+inline sin6_unique_ptr sin6p_to_v4mapped_in(const sin_unique_ptr& sinp) { return sin6_to_v4mapped_in(sinp.get()); }
3311+inline sin6_unique_ptr sin6p_to_v4mapped_in(const c_sin_unique_ptr& sinp) { return sin6_to_v4mapped_in(sinp.get()); }
3312+
3313+inline uint16_t sap_port(const sa_unique_ptr& sap) { return sa_port(sap.get()); }
3314+inline uint16_t sap_port(const c_sa_unique_ptr& sap) { return sa_port(sap.get()); }
3315+inline void sap_set_port(const sa_unique_ptr& sap, uint16_t port) { sa_set_port(sap.get(), port); }
3316+
3317+inline bool sap_equal(const sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
3318+inline bool sap_equal(const sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
3319+inline bool sap_equal(const c_sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
3320+inline bool sap_equal(const c_sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
3321+inline bool sinp_equal(const sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
3322+inline bool sinp_equal(const sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
3323+inline bool sinp_equal(const c_sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
3324+inline bool sinp_equal(const c_sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
3325+inline bool sin6p_equal(const sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
3326+inline bool sin6p_equal(const sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
3327+inline bool sin6p_equal(const c_sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
3328+inline bool sin6p_equal(const c_sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
3329+
3330+inline bool sap_equal_addr(const sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
3331+inline bool sap_equal_addr(const sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
3332+inline bool sap_equal_addr(const c_sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
3333+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()); }
3334+inline bool sinp_equal_addr(const sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
3335+inline bool sinp_equal_addr(const sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
3336+inline bool sinp_equal_addr(const c_sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
3337+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()); }
3338+inline bool sin6p_equal_addr(const sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
3339+inline bool sin6p_equal_addr(const sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
3340+inline bool sin6p_equal_addr(const c_sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
3341+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()); }
3342+
3343+inline std::string sap_addr_str(const sa_unique_ptr& sap) { return sa_addr_str(sap.get()); }
3344+inline std::string sap_addr_str(const c_sa_unique_ptr& sap) { return sa_addr_str(sap.get()); }
3345+inline std::string sap_pretty_str(const sa_unique_ptr& sap) { return sa_pretty_str(sap.get()); }
3346+inline std::string sap_pretty_str(const c_sa_unique_ptr& sap) { return sa_pretty_str(sap.get()); }
3347+
3348+//
3349+// Implementations:
3350+//
3351+
3352+inline sa_unique_ptr
3353+sa_from_v4mapped_in6(const sockaddr_in6* sin6) {
3354+ return sa_from_in(sin_from_v4mapped_in6(sin6));
3355+}
3356+
3357+inline sa_unique_ptr
3358+sa_to_v4mapped_in(const sockaddr_in* sin) {
3359+ return sa_from_in6(sin6_to_v4mapped_in(sin));
3360+}
3361+
3362+inline sa_unique_ptr
3363+sa_from_in(sin_unique_ptr&& sinp) {
3364+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sinp.release()));
3365+}
3366+
3367+inline c_sa_unique_ptr
3368+sa_from_in(c_sin_unique_ptr&& sinp) {
3369+ return c_sa_unique_ptr(reinterpret_cast<const sockaddr*>(sinp.release()));
3370+}
3371+
3372+inline sa_unique_ptr
3373+sa_from_in6(sin6_unique_ptr&& sin6p) {
3374+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sin6p.release()));
3375+}
3376+
3377+inline c_sa_unique_ptr
3378+sa_from_in6(c_sin6_unique_ptr&& sin6p) {
3379+ return c_sa_unique_ptr(reinterpret_cast<const sockaddr*>(sin6p.release()));
3380+}
3381+
3382+inline bool
3383+fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) {
3384+ return std::get<0>(lhs) == std::get<0>(rhs) && sap_equal(std::get<1>(lhs), std::get<1>(rhs));
3385+}
3386+
3387+}
3388+
3389+#endif
3390diff --git a/src/torrent/net/socket_address_key.h b/src/torrent/net/socket_address_key.h
3391index 9d6e0c49..0fd0feb3 100644
3392--- a/src/torrent/net/socket_address_key.h
3393+++ b/src/torrent/net/socket_address_key.h
3394@@ -5,7 +5,7 @@
3395 #define LIBTORRENT_UTILS_SOCKET_ADDRESS_KEY_H
3396
3397 #include <cstring>
3398-#include <inttypes.h>
3399+#include <cinttypes>
3400 #include <netinet/in.h>
3401
3402 // Unique key for the socket address, excluding port numbers, etc.
3403diff --git a/src/torrent/net/socket_event.cc b/src/torrent/net/socket_event.cc
3404new file mode 100644
3405index 00000000..e6805290
3406--- /dev/null
3407+++ b/src/torrent/net/socket_event.cc
3408@@ -0,0 +1,29 @@
3409+#include "config.h"
3410+
3411+#include "socket_event.h"
3412+
3413+#include "torrent/exceptions.h"
3414+
3415+namespace torrent {
3416+
3417+socket_event::~socket_event() {
3418+ if (is_open())
3419+ throw internal_error("Called socket_event::~socket_event while still open on type " + std::string(type_name()));
3420+}
3421+
3422+void
3423+socket_event::event_read() {
3424+ throw internal_error("Called unsupported socket_event::event_read on type " + std::string(type_name()));
3425+}
3426+
3427+void
3428+socket_event::event_write() {
3429+ throw internal_error("Called unsupported socket_event::event_write on type " + std::string(type_name()));
3430+}
3431+
3432+void
3433+socket_event::event_error() {
3434+ throw internal_error("Called unsupported socket_event::event_error on type " + std::string(type_name()));
3435+}
3436+
3437+}
3438diff --git a/src/torrent/net/socket_event.h b/src/torrent/net/socket_event.h
3439new file mode 100644
3440index 00000000..d9904bd6
3441--- /dev/null
3442+++ b/src/torrent/net/socket_event.h
3443@@ -0,0 +1,31 @@
3444+#ifndef LIBTORRENT_SOCKET_EVENT_H
3445+#define LIBTORRENT_SOCKET_EVENT_H
3446+
3447+#include <cinttypes>
3448+
3449+#include "torrent/event.h"
3450+#include "torrent/net/socket_address.h"
3451+
3452+namespace torrent {
3453+
3454+class LIBTORRENT_EXPORT socket_event : public Event {
3455+public:
3456+ ~socket_event() override;
3457+
3458+ const sockaddr* socket_address() const;
3459+ uint16_t socket_address_port() const;
3460+
3461+ void event_read() override;
3462+ void event_write() override;
3463+ void event_error() override;
3464+
3465+protected:
3466+ sa_unique_ptr m_socket_address;
3467+};
3468+
3469+inline const sockaddr* socket_event::socket_address() const { return m_socket_address.get(); }
3470+inline uint16_t socket_event::socket_address_port() const { return sap_port(m_socket_address); }
3471+
3472+}
3473+
3474+#endif
3475diff --git a/src/torrent/net/types.h b/src/torrent/net/types.h
3476new file mode 100644
3477index 00000000..016e8b85
3478--- /dev/null
3479+++ b/src/torrent/net/types.h
3480@@ -0,0 +1,33 @@
3481+#ifndef LIBTORRENT_NET_TYPES_H
3482+#define LIBTORRENT_NET_TYPES_H
3483+
3484+#include <memory>
3485+#include <tuple>
3486+#include <sys/socket.h>
3487+
3488+struct sockaddr_in;
3489+struct sockaddr_in6;
3490+struct sockaddr_un;
3491+
3492+namespace torrent {
3493+
3494+typedef std::unique_ptr<sockaddr> sa_unique_ptr;
3495+typedef std::unique_ptr<sockaddr_in> sin_unique_ptr;
3496+typedef std::unique_ptr<sockaddr_in6> sin6_unique_ptr;
3497+typedef std::unique_ptr<sockaddr_un> sun_unique_ptr;
3498+
3499+typedef std::unique_ptr<const sockaddr> c_sa_unique_ptr;
3500+typedef std::unique_ptr<const sockaddr_in> c_sin_unique_ptr;
3501+typedef std::unique_ptr<const sockaddr_in6> c_sin6_unique_ptr;
3502+typedef std::unique_ptr<const sockaddr_un> c_sun_unique_ptr;
3503+
3504+typedef std::tuple<int, std::unique_ptr<sockaddr>> fd_sap_tuple;
3505+
3506+struct listen_result_type {
3507+ int fd;
3508+ sa_unique_ptr address;
3509+};
3510+
3511+}
3512+
3513+#endif
3514diff --git a/src/torrent/object.h b/src/torrent/object.h
3515index 3325a434..3f9fe7e4 100644
3516--- a/src/torrent/object.h
3517+++ b/src/torrent/object.h
3518@@ -37,8 +37,9 @@
3519 #ifndef LIBTORRENT_OBJECT_H
3520 #define LIBTORRENT_OBJECT_H
3521
3522-#include <string>
3523+#include <limits>
3524 #include <map>
3525+#include <string>
3526 #include <vector>
3527 #include <torrent/common.h>
3528 #include <torrent/exceptions.h>
3529@@ -162,6 +163,7 @@ public:
3530 string_type& as_string() { check_throw(TYPE_STRING); return _string(); }
3531 const string_type& as_string() const { check_throw(TYPE_STRING); return _string(); }
3532 const string_type& as_string_c() const { check_throw(TYPE_STRING); return _string(); }
3533+ const char* as_c_str() const { check_throw(TYPE_STRING); return _string().c_str(); }
3534 list_type& as_list() { check_throw(TYPE_LIST); return _list(); }
3535 const list_type& as_list() const { check_throw(TYPE_LIST); return _list(); }
3536 map_type& as_map() { check_throw(TYPE_MAP); return _map(); }
3537@@ -179,6 +181,8 @@ public:
3538 raw_map& as_raw_map() { check_throw(TYPE_RAW_MAP); return _raw_map(); }
3539 const raw_map& as_raw_map() const { check_throw(TYPE_RAW_MAP); return _raw_map(); }
3540
3541+ template <typename T> T as_value_type(const char* err_msg) const { check_value_throw<T>(err_msg); return _value(); }
3542+
3543 bool has_key(const key_type& k) const { check_throw(TYPE_MAP); return _map().find(k) != _map().end(); }
3544 bool has_key_value(const key_type& k) const { check_throw(TYPE_MAP); return check(_map().find(k), TYPE_VALUE); }
3545 bool has_key_string(const key_type& k) const { check_throw(TYPE_MAP); return check(_map().find(k), TYPE_STRING); }
3546@@ -246,6 +250,8 @@ public:
3547 inline bool check(map_type::const_iterator itr, type_type t) const { return itr != _map().end() && itr->second.type() == t; }
3548 inline void check_throw(type_type t) const { if (t != type()) throw bencode_error("Wrong object type."); }
3549
3550+ template <typename T> void check_value_throw(const char* err_msg) const;
3551+
3552 uint32_t m_flags;
3553
3554 #ifndef HAVE_STDCXX_0X
3555@@ -484,6 +490,19 @@ object_equal(const Object& left, const Object& right) {
3556 }
3557 }
3558
3559+template <typename T>
3560+inline void
3561+Object::check_value_throw(const char* err_msg) const {
3562+ if (!std::numeric_limits<T>::is_integer)
3563+ throw internal_error("Tried to check value with non-integer type.");
3564+
3565+ if (!is_value())
3566+ throw bencode_error(err_msg);
3567+
3568+ if (!(_value() >= std::numeric_limits<T>::min() && _value() <= std::numeric_limits<T>::max()))
3569+ throw bencode_error(err_msg);
3570+}
3571+
3572 }
3573
3574 #endif
3575diff --git a/src/torrent/peer/client_list.cc b/src/torrent/peer/client_list.cc
3576index c857f62d..9c18aa50 100644
3577--- a/src/torrent/peer/client_list.cc
3578+++ b/src/torrent/peer/client_list.cc
3579@@ -37,8 +37,8 @@
3580 #include "config.h"
3581
3582 #include <algorithm>
3583+#include <functional>
3584 #include <rak/string_manip.h>
3585-#include lt_tr1_functional
3586
3587 #include "client_list.h"
3588 #include "exceptions.h"
3589diff --git a/src/torrent/peer/connection_list.h b/src/torrent/peer/connection_list.h
3590index ec26835f..eb058784 100644
3591--- a/src/torrent/peer/connection_list.h
3592+++ b/src/torrent/peer/connection_list.h
3593@@ -37,9 +37,10 @@
3594 #ifndef LIBTORRENT_PEER_CONNECTION_LIST_H
3595 #define LIBTORRENT_PEER_CONNECTION_LIST_H
3596
3597+#include <functional>
3598 #include <list>
3599 #include <vector>
3600-#include lt_tr1_functional
3601+
3602 #include <torrent/common.h>
3603 #include <torrent/hash_string.h>
3604
3605diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc
3606index aa60939a..080a7f13 100644
3607--- a/src/torrent/peer/peer_list.cc
3608+++ b/src/torrent/peer/peer_list.cc
3609@@ -36,8 +36,6 @@
3610
3611 #include "config.h"
3612
3613-#define __STDC_FORMAT_MACROS
3614-
3615 #include <algorithm>
3616 #include <functional>
3617 #include <rak/functional.h>
3618@@ -56,6 +54,8 @@
3619
3620 #define LT_LOG_EVENTS(log_fmt, ...) \
3621 lt_log_print_info(LOG_PEER_LIST_EVENTS, m_info, "peer_list", log_fmt, __VA_ARGS__);
3622+#define LT_LOG_ADDRESS(log_fmt, ...) \
3623+ lt_log_print_info(LOG_PEER_LIST_ADDRESS, m_info, "peer_list", log_fmt, __VA_ARGS__);
3624 #define LT_LOG_SA_FMT "'%s:%" PRIu16 "'"
3625
3626 namespace torrent {
3627@@ -196,6 +196,7 @@ PeerList::insert_available(const void* al) {
3628 for (; itr != last; itr++) {
3629 if (!socket_address_key::is_comparable_sockaddr(itr->c_sockaddr()) || itr->port() == 0) {
3630 invalid++;
3631+ LT_LOG_ADDRESS("skipped invalid address " LT_LOG_SA_FMT, itr->address_str().c_str(), itr->port());
3632 continue;
3633 }
3634
3635@@ -242,6 +243,8 @@ PeerList::insert_available(const void* al) {
3636
3637 inserted++;
3638 m_available_list->push_back(&*itr);
3639+
3640+ LT_LOG_ADDRESS("added available address " LT_LOG_SA_FMT, itr->address_str().c_str(), itr->port());
3641 }
3642
3643 LT_LOG_EVENTS("inserted peers"
3644diff --git a/src/torrent/poll.h b/src/torrent/poll.h
3645index b12c8ec2..15a73897 100644
3646--- a/src/torrent/poll.h
3647+++ b/src/torrent/poll.h
3648@@ -37,8 +37,7 @@
3649 #ifndef LIBTORRENT_TORRENT_POLL_H
3650 #define LIBTORRENT_TORRENT_POLL_H
3651
3652-#include lt_tr1_functional
3653-
3654+#include <functional>
3655 #include <torrent/common.h>
3656
3657 namespace torrent {
3658diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc
3659index 339c2c4f..fb70d247 100644
3660--- a/src/torrent/torrent.cc
3661+++ b/src/torrent/torrent.cc
3662@@ -1,39 +1,3 @@
3663-// libTorrent - BitTorrent library
3664-// Copyright (C) 2005-2011, Jari Sundell
3665-//
3666-// This program is free software; you can redistribute it and/or modify
3667-// it under the terms of the GNU General Public License as published by
3668-// the Free Software Foundation; either version 2 of the License, or
3669-// (at your option) any later version.
3670-//
3671-// This program is distributed in the hope that it will be useful,
3672-// but WITHOUT ANY WARRANTY; without even the implied warranty of
3673-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3674-// GNU General Public License for more details.
3675-//
3676-// You should have received a copy of the GNU General Public License
3677-// along with this program; if not, write to the Free Software
3678-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3679-//
3680-// In addition, as a special exception, the copyright holders give
3681-// permission to link the code of portions of this program with the
3682-// OpenSSL library under certain conditions as described in each
3683-// individual source file, and distribute linked combinations
3684-// including the two.
3685-//
3686-// You must obey the GNU General Public License in all respects for
3687-// all of the code used other than OpenSSL. If you modify file(s)
3688-// with this exception, you may extend this exception to your version
3689-// of the file(s), but you are not obligated to do so. If you do not
3690-// wish to do so, delete this exception statement from your version.
3691-// If you delete this exception statement from all source files in the
3692-// program, then also delete it here.
3693-//
3694-// Contact: Jari Sundell <jaris@ifi.uio.no>
3695-//
3696-// Skomakerveien 33
3697-// 3185 Skoppum, NORWAY
3698-
3699 #include "config.h"
3700
3701 #include <rak/address_info.h>
3702@@ -139,8 +103,8 @@ main_thread() {
3703
3704 ChunkManager* chunk_manager() { return manager->chunk_manager(); }
3705 ClientList* client_list() { return manager->client_list(); }
3706-FileManager* file_manager() { return manager->file_manager(); }
3707 ConnectionManager* connection_manager() { return manager->connection_manager(); }
3708+FileManager* file_manager() { return manager->file_manager(); }
3709 DhtManager* dht_manager() { return manager->dht_manager(); }
3710 ResourceManager* resource_manager() { return manager->resource_manager(); }
3711
3712@@ -189,8 +153,10 @@ download_add(Object* object) {
3713 download->main()->set_metadata_size(metadata_size);
3714 }
3715
3716+ std::string local_id = PEER_NAME + rak::generate_random<std::string>(20 - std::string(PEER_NAME).size());
3717+
3718 download->set_hash_queue(manager->hash_queue());
3719- download->initialize(infoHash, PEER_NAME + rak::generate_random<std::string>(20 - std::string(PEER_NAME).size()));
3720+ download->initialize(infoHash, local_id);
3721
3722 // Add trackers, etc, after setting the info hash so that log
3723 // entries look sane.
3724diff --git a/src/torrent/torrent.h b/src/torrent/torrent.h
3725index 7bcf88fe..0cdfdaa7 100644
3726--- a/src/torrent/torrent.h
3727+++ b/src/torrent/torrent.h
3728@@ -44,6 +44,11 @@
3729
3730 namespace torrent {
3731
3732+class FileManager;
3733+class ResourceManager;
3734+
3735+class thread_base;
3736+
3737 // Make sure you seed srandom and srand48 if available.
3738 void initialize() LIBTORRENT_EXPORT;
3739
3740@@ -53,16 +58,12 @@ void cleanup() LIBTORRENT_EXPORT;
3741
3742 bool is_inactive() LIBTORRENT_EXPORT;
3743
3744-class FileManager;
3745-class ResourceManager;
3746-class thread_base;
3747-
3748 thread_base* main_thread() LIBTORRENT_EXPORT;
3749
3750 ChunkManager* chunk_manager() LIBTORRENT_EXPORT;
3751 ClientList* client_list() LIBTORRENT_EXPORT;
3752-FileManager* file_manager() LIBTORRENT_EXPORT;
3753 ConnectionManager* connection_manager() LIBTORRENT_EXPORT;
3754+FileManager* file_manager() LIBTORRENT_EXPORT;
3755 DhtManager* dht_manager() LIBTORRENT_EXPORT;
3756 ResourceManager* resource_manager() LIBTORRENT_EXPORT;
3757
3758diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h
3759index a528ef6a..bd7546a9 100644
3760--- a/src/torrent/tracker.h
3761+++ b/src/torrent/tracker.h
3762@@ -2,7 +2,7 @@
3763 #define LIBTORRENT_TRACKER_H
3764
3765 #include <string>
3766-#include <inttypes.h>
3767+#include <cinttypes>
3768 #include <torrent/common.h>
3769
3770 namespace torrent {
3771diff --git a/src/torrent/tracker_controller.h b/src/torrent/tracker_controller.h
3772index 70d1b43f..9452be0f 100644
3773--- a/src/torrent/tracker_controller.h
3774+++ b/src/torrent/tracker_controller.h
3775@@ -37,8 +37,9 @@
3776 #ifndef LIBTORRENT_TRACKER_CONTROLLER_H
3777 #define LIBTORRENT_TRACKER_CONTROLLER_H
3778
3779+#include <functional>
3780 #include <string>
3781-#include lt_tr1_functional
3782+
3783 #include <torrent/common.h>
3784 #include <torrent/tracker.h>
3785
3786diff --git a/src/torrent/tracker_list.h b/src/torrent/tracker_list.h
3787index c6817b3a..bb06f8af 100644
3788--- a/src/torrent/tracker_list.h
3789+++ b/src/torrent/tracker_list.h
3790@@ -38,10 +38,10 @@
3791 #define LIBTORRENT_TRACKER_LIST_H
3792
3793 #include <algorithm>
3794+#include <functional>
3795 #include <string>
3796 #include <vector>
3797 #include <torrent/common.h>
3798-#include lt_tr1_functional
3799
3800 namespace torrent {
3801
3802diff --git a/src/torrent/utils/Makefile.am b/src/torrent/utils/Makefile.am
3803index 51c9a026..a48786c6 100644
3804--- a/src/torrent/utils/Makefile.am
3805+++ b/src/torrent/utils/Makefile.am
3806@@ -8,10 +8,10 @@ libsub_torrentutils_la_SOURCES = \
3807 log.h \
3808 log_buffer.cc \
3809 log_buffer.h \
3810- net.cc \
3811- net.h \
3812 option_strings.cc \
3813 option_strings.h \
3814+ random.cc \
3815+ random.h \
3816 ranges.h \
3817 resume.cc \
3818 resume.h \
3819@@ -32,7 +32,6 @@ libtorrentinclude_HEADERS = \
3820 extents.h \
3821 log.h \
3822 log_buffer.h \
3823- net.h \
3824 option_strings.h \
3825 ranges.h \
3826 resume.h \
3827diff --git a/src/torrent/utils/directory_events.h b/src/torrent/utils/directory_events.h
3828index 30fa0508..fd9246c5 100644
3829--- a/src/torrent/utils/directory_events.h
3830+++ b/src/torrent/utils/directory_events.h
3831@@ -37,9 +37,10 @@
3832 #ifndef LIBTORRENT_DIRECTORY_EVENTS_H
3833 #define LIBTORRENT_DIRECTORY_EVENTS_H
3834
3835+#include <functional>
3836 #include <string>
3837 #include <vector>
3838-#include lt_tr1_functional
3839+
3840 #include <torrent/event.h>
3841
3842 namespace torrent {
3843diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
3844index 6c605474..b855a2c6 100644
3845--- a/src/torrent/utils/log.cc
3846+++ b/src/torrent/utils/log.cc
3847@@ -1,45 +1,6 @@
3848-// libTorrent - BitTorrent library
3849-// Copyright (C) 2005-2011, Jari Sundell
3850-//
3851-// This program is free software; you can redistribute it and/or modify
3852-// it under the terms of the GNU General Public License as published by
3853-// the Free Software Foundation; either version 2 of the License, or
3854-// (at your option) any later version.
3855-//
3856-// This program is distributed in the hope that it will be useful,
3857-// but WITHOUT ANY WARRANTY; without even the implied warranty of
3858-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3859-// GNU General Public License for more details.
3860-//
3861-// You should have received a copy of the GNU General Public License
3862-// along with this program; if not, write to the Free Software
3863-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3864-//
3865-// In addition, as a special exception, the copyright holders give
3866-// permission to link the code of portions of this program with the
3867-// OpenSSL library under certain conditions as described in each
3868-// individual source file, and distribute linked combinations
3869-// including the two.
3870-//
3871-// You must obey the GNU General Public License in all respects for
3872-// all of the code used other than OpenSSL. If you modify file(s)
3873-// with this exception, you may extend this exception to your version
3874-// of the file(s), but you are not obligated to do so. If you do not
3875-// wish to do so, delete this exception statement from your version.
3876-// If you delete this exception statement from all source files in the
3877-// program, then also delete it here.
3878-//
3879-// Contact: Jari Sundell <jaris@ifi.uio.no>
3880-//
3881-// Skomakerveien 33
3882-// 3185 Skoppum, NORWAY
3883-
3884 #include "config.h"
3885
3886-#define __STDC_FORMAT_MACROS
3887-
3888 #include "log.h"
3889-#include "log_buffer.h"
3890
3891 #include "globals.h"
3892 #include "torrent/exceptions.h"
3893@@ -54,8 +15,6 @@
3894 #include <fstream>
3895 #include <functional>
3896 #include <memory>
3897-#include lt_tr1_functional
3898-#include lt_tr1_memory
3899
3900 namespace torrent {
3901
3902@@ -232,7 +191,6 @@ log_initialize() {
3903
3904 LOG_CASCADE(LOG_CRITICAL);
3905
3906- LOG_CASCADE(LOG_CONNECTION_CRITICAL);
3907 LOG_CASCADE(LOG_PEER_CRITICAL);
3908 LOG_CASCADE(LOG_SOCKET_CRITICAL);
3909 LOG_CASCADE(LOG_STORAGE_CRITICAL);
3910@@ -240,7 +198,6 @@ log_initialize() {
3911 LOG_CASCADE(LOG_TRACKER_CRITICAL);
3912 LOG_CASCADE(LOG_TORRENT_CRITICAL);
3913
3914- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_CONNECTION_CRITICAL);
3915 LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_PEER_CRITICAL);
3916 LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_SOCKET_CRITICAL);
3917 LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_STORAGE_CRITICAL);
3918@@ -248,6 +205,12 @@ log_initialize() {
3919 LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_TRACKER_CRITICAL);
3920 LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_TORRENT_CRITICAL);
3921
3922+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_BIND);
3923+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_FD);
3924+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_FILTER);
3925+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_HANDSHAKE);
3926+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_LISTEN);
3927+
3928 LOG_LINK(LOG_DHT_ALL, LOG_DHT_MANAGER);
3929 LOG_LINK(LOG_DHT_ALL, LOG_DHT_NODE);
3930 LOG_LINK(LOG_DHT_ALL, LOG_DHT_ROUTER);
3931@@ -447,21 +410,4 @@ log_open_gz_file_output(const char* name, const char* filename, bool append) {
3932 std::placeholders::_3));
3933 }
3934
3935-log_buffer*
3936-log_open_log_buffer(const char* name) {
3937- log_buffer* buffer = new log_buffer;
3938-
3939- try {
3940- log_open_output(name, std::bind(&log_buffer::lock_and_push_log, buffer,
3941- std::placeholders::_1,
3942- std::placeholders::_2,
3943- std::placeholders::_3));
3944- return buffer;
3945-
3946- } catch (torrent::input_error& e) {
3947- delete buffer;
3948- throw;
3949- }
3950-}
3951-
3952 }
3953diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
3954index 0dfdc86b..fe6127d6 100644
3955--- a/src/torrent/utils/log.h
3956+++ b/src/torrent/utils/log.h
3957@@ -1,47 +1,12 @@
3958-// libTorrent - BitTorrent library
3959-// Copyright (C) 2005-2011, Jari Sundell
3960-//
3961-// This program is free software; you can redistribute it and/or modify
3962-// it under the terms of the GNU General Public License as published by
3963-// the Free Software Foundation; either version 2 of the License, or
3964-// (at your option) any later version.
3965-//
3966-// This program is distributed in the hope that it will be useful,
3967-// but WITHOUT ANY WARRANTY; without even the implied warranty of
3968-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3969-// GNU General Public License for more details.
3970-//
3971-// You should have received a copy of the GNU General Public License
3972-// along with this program; if not, write to the Free Software
3973-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3974-//
3975-// In addition, as a special exception, the copyright holders give
3976-// permission to link the code of portions of this program with the
3977-// OpenSSL library under certain conditions as described in each
3978-// individual source file, and distribute linked combinations
3979-// including the two.
3980-//
3981-// You must obey the GNU General Public License in all respects for
3982-// all of the code used other than OpenSSL. If you modify file(s)
3983-// with this exception, you may extend this exception to your version
3984-// of the file(s), but you are not obligated to do so. If you do not
3985-// wish to do so, delete this exception statement from your version.
3986-// If you delete this exception statement from all source files in the
3987-// program, then also delete it here.
3988-//
3989-// Contact: Jari Sundell <jaris@ifi.uio.no>
3990-//
3991-// Skomakerveien 33
3992-// 3185 Skoppum, NORWAY
3993-
3994 #ifndef LIBTORRENT_UTILS_LOG_H
3995 #define LIBTORRENT_UTILS_LOG_H
3996
3997+#include <array>
3998 #include <bitset>
3999+#include <functional>
4000 #include <string>
4001 #include <vector>
4002-#include lt_tr1_array
4003-#include lt_tr1_functional
4004+
4005 #include <torrent/common.h>
4006
4007 namespace torrent {
4008@@ -55,13 +20,6 @@ enum {
4009 LOG_INFO,
4010 LOG_DEBUG,
4011
4012- LOG_CONNECTION_CRITICAL,
4013- LOG_CONNECTION_ERROR,
4014- LOG_CONNECTION_WARN,
4015- LOG_CONNECTION_NOTICE,
4016- LOG_CONNECTION_INFO,
4017- LOG_CONNECTION_DEBUG,
4018-
4019 LOG_DHT_CRITICAL,
4020 LOG_DHT_ERROR,
4021 LOG_DHT_WARN,
4022@@ -113,6 +71,14 @@ enum {
4023
4024 LOG_NON_CASCADING,
4025
4026+ LOG_CONNECTION,
4027+ LOG_CONNECTION_BIND,
4028+ LOG_CONNECTION_FD,
4029+ LOG_CONNECTION_FILTER,
4030+ LOG_CONNECTION_HANDSHAKE,
4031+ LOG_CONNECTION_LISTEN,
4032+
4033+ // TODO: Rename dht_all to just dht.
4034 LOG_DHT_ALL,
4035 LOG_DHT_MANAGER,
4036 LOG_DHT_NODE,
4037@@ -125,7 +91,10 @@ enum {
4038 LOG_INSTRUMENTATION_POLLING,
4039 LOG_INSTRUMENTATION_TRANSFERS,
4040
4041+ LOG_MOCK_CALLS,
4042+
4043 LOG_PEER_LIST_EVENTS,
4044+ LOG_PEER_LIST_ADDRESS,
4045
4046 LOG_PROTOCOL_PIECE_EVENTS,
4047 LOG_PROTOCOL_METADATA_EVENTS,
4048@@ -137,6 +106,8 @@ enum {
4049 LOG_RPC_EVENTS,
4050 LOG_RPC_DUMP,
4051
4052+ LOG_SYSTEM,
4053+
4054 LOG_UI_EVENTS,
4055
4056 LOG_GROUP_MAX_SIZE
4057@@ -145,34 +116,32 @@ enum {
4058 #define lt_log_is_valid(log_group) (torrent::log_groups[log_group].valid())
4059
4060 #define lt_log_print(log_group, ...) \
4061- if (torrent::log_groups[log_group].valid()) \
4062- torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__);
4063+ { if (torrent::log_groups[log_group].valid()) \
4064+ torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__); }
4065
4066 #define lt_log_print_info(log_group, log_info, log_subsystem, ...) \
4067- if (torrent::log_groups[log_group].valid()) \
4068- torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__);
4069+ { if (torrent::log_groups[log_group].valid()) \
4070+ torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__); }
4071
4072 #define lt_log_print_data(log_group, log_data, log_subsystem, ...) \
4073- if (torrent::log_groups[log_group].valid()) \
4074- torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__);
4075+ { if (torrent::log_groups[log_group].valid()) \
4076+ torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__); }
4077
4078 #define lt_log_print_dump(log_group, log_dump_data, log_dump_size, ...) \
4079- if (torrent::log_groups[log_group].valid()) \
4080- torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); \
4081+ { if (torrent::log_groups[log_group].valid()) \
4082+ torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); }
4083
4084 #define lt_log_print_hash(log_group, log_hash, log_subsystem, ...) \
4085- if (torrent::log_groups[log_group].valid()) \
4086- torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__);
4087+ { if (torrent::log_groups[log_group].valid()) \
4088+ torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__); }
4089
4090 #define lt_log_print_info_dump(log_group, log_dump_data, log_dump_size, log_info, log_subsystem, ...) \
4091- if (torrent::log_groups[log_group].valid()) \
4092- torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); \
4093+ { if (torrent::log_groups[log_group].valid()) \
4094+ torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); }
4095
4096 #define lt_log_print_subsystem(log_group, log_subsystem, ...) \
4097- if (torrent::log_groups[log_group].valid()) \
4098- torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__);
4099-
4100-class log_buffer;
4101+ { if (torrent::log_groups[log_group].valid()) \
4102+ torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__); }
4103
4104 typedef std::function<void (const char*, unsigned int, int)> log_slot;
4105
4106@@ -222,7 +191,7 @@ private:
4107
4108 typedef std::array<log_group, LOG_GROUP_MAX_SIZE> log_group_list;
4109
4110-extern log_group_list log_groups LIBTORRENT_EXPORT;
4111+extern log_group_list log_groups LIBTORRENT_EXPORT;
4112
4113 void log_initialize() LIBTORRENT_EXPORT;
4114 void log_cleanup() LIBTORRENT_EXPORT;
4115@@ -237,9 +206,8 @@ void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
4116 void log_add_child(int group, int child) LIBTORRENT_EXPORT;
4117 void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
4118
4119-void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
4120-void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
4121-log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
4122+void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
4123+void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
4124
4125 //
4126 // Implementation:
4127diff --git a/src/torrent/utils/log_buffer.cc b/src/torrent/utils/log_buffer.cc
4128index f82d57e0..5bf159a4 100644
4129--- a/src/torrent/utils/log_buffer.cc
4130+++ b/src/torrent/utils/log_buffer.cc
4131@@ -1,46 +1,8 @@
4132-// libTorrent - BitTorrent library
4133-// Copyright (C) 2005-2011, Jari Sundell
4134-//
4135-// This program is free software; you can redistribute it and/or modify
4136-// it under the terms of the GNU General Public License as published by
4137-// the Free Software Foundation; either version 2 of the License, or
4138-// (at your option) any later version.
4139-//
4140-// This program is distributed in the hope that it will be useful,
4141-// but WITHOUT ANY WARRANTY; without even the implied warranty of
4142-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4143-// GNU General Public License for more details.
4144-//
4145-// You should have received a copy of the GNU General Public License
4146-// along with this program; if not, write to the Free Software
4147-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4148-//
4149-// In addition, as a special exception, the copyright holders give
4150-// permission to link the code of portions of this program with the
4151-// OpenSSL library under certain conditions as described in each
4152-// individual source file, and distribute linked combinations
4153-// including the two.
4154-//
4155-// You must obey the GNU General Public License in all respects for
4156-// all of the code used other than OpenSSL. If you modify file(s)
4157-// with this exception, you may extend this exception to your version
4158-// of the file(s), but you are not obligated to do so. If you do not
4159-// wish to do so, delete this exception statement from your version.
4160-// If you delete this exception statement from all source files in the
4161-// program, then also delete it here.
4162-//
4163-// Contact: Jari Sundell <jaris@ifi.uio.no>
4164-//
4165-// Skomakerveien 33
4166-// 3185 Skoppum, NORWAY
4167-
4168 #include "config.h"
4169
4170 #include "log_buffer.h"
4171
4172-#include <functional>
4173-#include lt_tr1_functional
4174-
4175+#include "log.h"
4176 #include "globals.h"
4177
4178 namespace torrent {
4179@@ -72,4 +34,19 @@ log_buffer::lock_and_push_log(const char* data, size_t length, int group) {
4180 unlock();
4181 }
4182
4183+static void
4184+log_buffer_deleter(log_buffer* lb) {
4185+ delete lb;
4186+}
4187+
4188+log_buffer_ptr
4189+log_open_log_buffer(const char* name) {
4190+ // TODO: Deregister when deleting.
4191+ auto buffer = log_buffer_ptr(new log_buffer, std::bind(&log_buffer_deleter, std::placeholders::_1));
4192+
4193+ log_open_output(name, std::bind(&log_buffer::lock_and_push_log, buffer.get(),
4194+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
4195+ return buffer;
4196+}
4197+
4198 }
4199diff --git a/src/torrent/utils/log_buffer.h b/src/torrent/utils/log_buffer.h
4200index befd780b..259e5910 100644
4201--- a/src/torrent/utils/log_buffer.h
4202+++ b/src/torrent/utils/log_buffer.h
4203@@ -1,47 +1,11 @@
4204-// libTorrent - BitTorrent library
4205-// Copyright (C) 2005-2011, Jari Sundell
4206-//
4207-// This program is free software; you can redistribute it and/or modify
4208-// it under the terms of the GNU General Public License as published by
4209-// the Free Software Foundation; either version 2 of the License, or
4210-// (at your option) any later version.
4211-//
4212-// This program is distributed in the hope that it will be useful,
4213-// but WITHOUT ANY WARRANTY; without even the implied warranty of
4214-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4215-// GNU General Public License for more details.
4216-//
4217-// You should have received a copy of the GNU General Public License
4218-// along with this program; if not, write to the Free Software
4219-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4220-//
4221-// In addition, as a special exception, the copyright holders give
4222-// permission to link the code of portions of this program with the
4223-// OpenSSL library under certain conditions as described in each
4224-// individual source file, and distribute linked combinations
4225-// including the two.
4226-//
4227-// You must obey the GNU General Public License in all respects for
4228-// all of the code used other than OpenSSL. If you modify file(s)
4229-// with this exception, you may extend this exception to your version
4230-// of the file(s), but you are not obligated to do so. If you do not
4231-// wish to do so, delete this exception statement from your version.
4232-// If you delete this exception statement from all source files in the
4233-// program, then also delete it here.
4234-//
4235-// Contact: Jari Sundell <jaris@ifi.uio.no>
4236-//
4237-// Skomakerveien 33
4238-// 3185 Skoppum, NORWAY
4239-
4240-#ifndef LIBTORRENT_UTILS_LOG_BUFFER_H
4241-#define LIBTORRENT_UTILS_LOG_BUFFER_H
4242+#ifndef LIBTORRENT_TORRENT_UTILS_LOG_BUFFER_H
4243+#define LIBTORRENT_TORRENT_UTILS_LOG_BUFFER_H
4244
4245 #include <string>
4246 #include <deque>
4247+#include <functional>
4248+#include <memory>
4249 #include <pthread.h>
4250-#include lt_tr1_functional
4251-#include <torrent/common.h>
4252
4253 namespace torrent {
4254
4255@@ -57,9 +21,9 @@ struct log_entry {
4256 std::string message;
4257 };
4258
4259-class LIBTORRENT_EXPORT log_buffer : private std::deque<log_entry> {
4260+class [[gnu::visibility("default")]] log_buffer : private std::deque<log_entry> {
4261 public:
4262- typedef std::deque<log_entry> base_type;
4263+ typedef std::deque<log_entry> base_type;
4264 typedef std::function<void ()> slot_void;
4265
4266 using base_type::iterator;
4267@@ -97,6 +61,10 @@ private:
4268 slot_void m_slot_update;
4269 };
4270
4271+typedef std::unique_ptr<log_buffer, std::function<void (log_buffer*)>> log_buffer_ptr;
4272+
4273+[[gnu::visibility("default")]] log_buffer_ptr log_open_log_buffer(const char* name);
4274+
4275 }
4276
4277 #endif
4278diff --git a/src/torrent/utils/net.cc b/src/torrent/utils/net.cc
4279deleted file mode 100644
4280index 83c9b506..00000000
4281--- a/src/torrent/utils/net.cc
4282+++ /dev/null
4283@@ -1,72 +0,0 @@
4284-// libTorrent - BitTorrent library
4285-// Copyright (C) 2005-2011, Jari Sundell
4286-//
4287-// This program is free software; you can redistribute it and/or modify
4288-// it under the terms of the GNU General Public License as published by
4289-// the Free Software Foundation; either version 2 of the License, or
4290-// (at your option) any later version.
4291-//
4292-// This program is distributed in the hope that it will be useful,
4293-// but WITHOUT ANY WARRANTY; without even the implied warranty of
4294-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4295-// GNU General Public License for more details.
4296-//
4297-// You should have received a copy of the GNU General Public License
4298-// along with this program; if not, write to the Free Software
4299-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4300-//
4301-// In addition, as a special exception, the copyright holders give
4302-// permission to link the code of portions of this program with the
4303-// OpenSSL library under certain conditions as described in each
4304-// individual source file, and distribute linked combinations
4305-// including the two.
4306-//
4307-// You must obey the GNU General Public License in all respects for
4308-// all of the code used other than OpenSSL. If you modify file(s)
4309-// with this exception, you may extend this exception to your version
4310-// of the file(s), but you are not obligated to do so. If you do not
4311-// wish to do so, delete this exception statement from your version.
4312-// If you delete this exception statement from all source files in the
4313-// program, then also delete it here.
4314-//
4315-// Contact: Jari Sundell <jaris@ifi.uio.no>
4316-//
4317-// Skomakerveien 33
4318-// 3185 Skoppum, NORWAY
4319-
4320-#include "config.h"
4321-
4322-#include "net.h"
4323-#include "exceptions.h"
4324-
4325-#include <cstring>
4326-
4327-namespace torrent {
4328-
4329-addrinfo*
4330-address_info_lookup(const char* hostname, int family, int socktype) {
4331- addrinfo hints;
4332- std::memset(&hints, 0, sizeof(addrinfo));
4333- hints.ai_family = family;
4334- hints.ai_socktype = socktype;
4335-
4336- addrinfo* res = NULL;
4337- int err = ::getaddrinfo(hostname, NULL, &hints, &res);
4338-
4339- if (err)
4340- throw address_info_error(err);
4341-
4342- return res;
4343-}
4344-
4345-bool
4346-address_info_call(addrinfo* ai, int flags, slot_ai_success slot_success) {
4347- while (ai != NULL) {
4348- slot_success(ai->ai_addr, ai->ai_addrlen);
4349- return true;
4350- }
4351-
4352- return false;
4353-}
4354-
4355-}
4356diff --git a/src/torrent/utils/net.h b/src/torrent/utils/net.h
4357deleted file mode 100644
4358index f5af7cc0..00000000
4359--- a/src/torrent/utils/net.h
4360+++ /dev/null
4361@@ -1,56 +0,0 @@
4362-// libTorrent - BitTorrent library
4363-// Copyright (C) 2005-2011, Jari Sundell
4364-//
4365-// This program is free software; you can redistribute it and/or modify
4366-// it under the terms of the GNU General Public License as published by
4367-// the Free Software Foundation; either version 2 of the License, or
4368-// (at your option) any later version.
4369-//
4370-// This program is distributed in the hope that it will be useful,
4371-// but WITHOUT ANY WARRANTY; without even the implied warranty of
4372-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4373-// GNU General Public License for more details.
4374-//
4375-// You should have received a copy of the GNU General Public License
4376-// along with this program; if not, write to the Free Software
4377-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4378-//
4379-// In addition, as a special exception, the copyright holders give
4380-// permission to link the code of portions of this program with the
4381-// OpenSSL library under certain conditions as described in each
4382-// individual source file, and distribute linked combinations
4383-// including the two.
4384-//
4385-// You must obey the GNU General Public License in all respects for
4386-// all of the code used other than OpenSSL. If you modify file(s)
4387-// with this exception, you may extend this exception to your version
4388-// of the file(s), but you are not obligated to do so. If you do not
4389-// wish to do so, delete this exception statement from your version.
4390-// If you delete this exception statement from all source files in the
4391-// program, then also delete it here.
4392-//
4393-// Contact: Jari Sundell <jaris@ifi.uio.no>
4394-//
4395-// Skomakerveien 33
4396-// 3185 Skoppum, NORWAY
4397-
4398-#ifndef LIBTORRENT_UTILS_NET_H
4399-#define LIBTORRENT_UTILS_NET_H
4400-
4401-#include <netdb.h>
4402-#include lt_tr1_functional
4403-
4404-namespace torrent {
4405-
4406-typedef std::function<void (sockaddr*, socklen_t)> slot_ai_success;
4407-//typedef std::function<void (const char*, int)> slot_ai_failure;
4408-
4409-// Throws address_info_error on lookup failure.
4410-addrinfo* address_info_lookup(const char* hostname, int family, int socktype);
4411-inline void address_info_free(addrinfo* ai) { ::freeaddrinfo(ai); }
4412-
4413-bool address_info_call(addrinfo* ai, int flags, slot_ai_success slot_success);
4414-
4415-}
4416-
4417-#endif
4418diff --git a/src/torrent/utils/option_strings.cc b/src/torrent/utils/option_strings.cc
4419index 5992cf37..101e2688 100644
4420--- a/src/torrent/utils/option_strings.cc
4421+++ b/src/torrent/utils/option_strings.cc
4422@@ -62,7 +62,7 @@ struct option_pair {
4423 unsigned int value;
4424 };
4425
4426-option_pair option_list_connection[] = {
4427+option_pair option_list_connection_type[] = {
4428 { "leech", Download::CONNECTION_LEECH },
4429 { "seed", Download::CONNECTION_SEED },
4430 { "initial_seed", Download::CONNECTION_INITIAL_SEED },
4431@@ -124,6 +124,19 @@ option_pair option_list_tracker_mode[] = {
4432 { NULL, 0 }
4433 };
4434
4435+const char* option_list_handshake_connection[] = {
4436+ "none",
4437+ "incoming",
4438+ "outgoing_normal",
4439+ "outgoing_encrypted",
4440+ "outgoing_proxy",
4441+ "success",
4442+ "dropped",
4443+ "failed",
4444+ "retry_plaintext",
4445+ "retry_encrypted"
4446+};
4447+
4448 const char* option_list_log_group[] = {
4449 "critical",
4450 "error",
4451@@ -132,13 +145,6 @@ const char* option_list_log_group[] = {
4452 "info",
4453 "debug",
4454
4455- "connection_critical",
4456- "connection_error",
4457- "connection_warn",
4458- "connection_notice",
4459- "connection_info",
4460- "connection_debug",
4461-
4462 "dht_critical",
4463 "dht_error",
4464 "dht_warn",
4465@@ -190,6 +196,13 @@ const char* option_list_log_group[] = {
4466
4467 "__non_cascading__",
4468
4469+ "connection",
4470+ "connection_bind",
4471+ "connection_fd",
4472+ "connection_filter",
4473+ "connection_hanshake",
4474+ "connection_listen",
4475+
4476 "dht_all",
4477 "dht_manager",
4478 "dht_node",
4479@@ -202,7 +215,10 @@ const char* option_list_log_group[] = {
4480 "instrumentation_polling",
4481 "instrumentation_transfers",
4482
4483+ "mock_calls",
4484+
4485 "peer_list_events",
4486+ "peer_list_address",
4487
4488 "protocol_piece_events",
4489 "protocol_metadata_events",
4490@@ -214,6 +230,8 @@ const char* option_list_log_group[] = {
4491 "rpc_events",
4492 "rpc_dump",
4493
4494+ "system",
4495+
4496 "ui_events",
4497
4498 NULL
4499@@ -230,7 +248,7 @@ const char* option_list_tracker_event[] = {
4500 };
4501
4502 option_pair* option_pair_lists[OPTION_START_COMPACT] = {
4503- option_list_connection,
4504+ option_list_connection_type,
4505 option_list_heuristics,
4506 option_list_heuristics_download,
4507 option_list_heuristics_upload,
4508@@ -244,6 +262,7 @@ option_pair* option_pair_lists[OPTION_START_COMPACT] = {
4509 { sizeof(single_name) / sizeof(const char*) - 1, single_name }
4510
4511 option_single option_single_lists[OPTION_SINGLE_SIZE] = {
4512+ OPTION_SINGLE_ENTRY(option_list_handshake_connection),
4513 OPTION_SINGLE_ENTRY(option_list_log_group),
4514 OPTION_SINGLE_ENTRY(option_list_tracker_event),
4515 };
4516@@ -267,11 +286,11 @@ option_find_string(option_enum opt_enum, const char* name) {
4517 } while (*++itr != NULL);
4518 }
4519
4520- throw input_error("Invalid option name.");
4521+ throw input_error("Invalid option name.");
4522 }
4523
4524 const char*
4525-option_as_string(option_enum opt_enum, unsigned int value) {
4526+option_to_string(option_enum opt_enum, unsigned int value, const char* not_found) {
4527 if (opt_enum < OPTION_START_COMPACT) {
4528 option_pair* itr = option_pair_lists[opt_enum];
4529
4530@@ -285,7 +304,27 @@ option_as_string(option_enum opt_enum, unsigned int value) {
4531 return option_single_lists[opt_enum - OPTION_START_COMPACT].name[value];
4532 }
4533
4534- throw input_error("Invalid option value.");
4535+ return not_found;
4536+}
4537+
4538+const char*
4539+option_to_string_or_throw(option_enum opt_enum, unsigned int value, const char* not_found) {
4540+ const char* result = option_to_string(opt_enum, value, NULL);
4541+
4542+ if (result == NULL)
4543+ throw input_error(not_found);
4544+ else
4545+ return result;
4546+}
4547+
4548+const char*
4549+option_as_string(option_enum opt_enum, unsigned int value) {
4550+ const char* result = option_to_string(opt_enum, value, NULL);
4551+
4552+ if (result == NULL)
4553+ throw input_error("Invalid option value.");
4554+ else
4555+ return result;
4556 }
4557
4558 torrent::Object
4559diff --git a/src/torrent/utils/option_strings.h b/src/torrent/utils/option_strings.h
4560index 1b57efa8..f9e5ef77 100644
4561--- a/src/torrent/utils/option_strings.h
4562+++ b/src/torrent/utils/option_strings.h
4563@@ -54,17 +54,22 @@ enum option_enum {
4564 OPTION_IP_TOS,
4565 OPTION_TRACKER_MODE,
4566
4567+ OPTION_HANDSHAKE_CONNECTION,
4568 OPTION_LOG_GROUP,
4569 OPTION_TRACKER_EVENT,
4570
4571 OPTION_MAX_SIZE,
4572- OPTION_START_COMPACT = OPTION_LOG_GROUP,
4573+ OPTION_START_COMPACT = OPTION_HANDSHAKE_CONNECTION,
4574 OPTION_SINGLE_SIZE = OPTION_MAX_SIZE - OPTION_START_COMPACT
4575 };
4576
4577 int option_find_string(option_enum opt_enum, const char* name) LIBTORRENT_EXPORT;
4578 inline int option_find_string_str(option_enum opt_enum, const std::string& name) { return option_find_string(opt_enum, name.c_str()); }
4579
4580+const char* option_to_string(option_enum opt_enum, unsigned int value, const char* not_found = "invalid") LIBTORRENT_EXPORT;
4581+const char* option_to_string_or_throw(option_enum opt_enum, unsigned int value, const char* not_found = "Invalid option value") LIBTORRENT_EXPORT;
4582+
4583+// TODO: Deprecated.
4584 const char* option_as_string(option_enum opt_enum, unsigned int value) LIBTORRENT_EXPORT;
4585
4586 torrent::Object option_list_strings(option_enum opt_enum) LIBTORRENT_EXPORT;
4587diff --git a/src/torrent/utils/random.cc b/src/torrent/utils/random.cc
4588new file mode 100644
4589index 00000000..6a045429
4590--- /dev/null
4591+++ b/src/torrent/utils/random.cc
4592@@ -0,0 +1,29 @@
4593+#include "config.h"
4594+
4595+#include "random.h"
4596+
4597+#include "torrent/exceptions.h"
4598+
4599+namespace torrent {
4600+
4601+// TODO: Replace with std and thread_local generator.
4602+
4603+template <typename T>
4604+T
4605+random_uniform_template(T min, T max) {
4606+ if (min > max)
4607+ throw internal_error("random_uniform: min > max");
4608+
4609+ if (min == max)
4610+ return min;
4611+
4612+ std::random_device rd;
4613+ std::mt19937 mt(rd());
4614+
4615+ return min + std::uniform_int_distribution<T>(min, max)(mt) % (max - min + 1);
4616+}
4617+
4618+uint16_t random_uniform_uint16(uint16_t min, uint16_t max) { return random_uniform_template<uint16_t>(min, max); }
4619+uint32_t random_uniform_uint32(uint32_t min, uint32_t max) { return random_uniform_template<uint32_t>(min, max); }
4620+
4621+}
4622diff --git a/src/torrent/utils/random.h b/src/torrent/utils/random.h
4623new file mode 100644
4624index 00000000..d5992ab6
4625--- /dev/null
4626+++ b/src/torrent/utils/random.h
4627@@ -0,0 +1,15 @@
4628+#ifndef LIBTORRENT_TORRENT_UTILS_RANDOM_H
4629+#define LIBTORRENT_TORRENT_UTILS_RANDOM_H
4630+
4631+#include <cinttypes>
4632+#include <limits>
4633+#include <random>
4634+
4635+namespace torrent {
4636+
4637+[[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());
4638+[[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());
4639+
4640+}
4641+
4642+#endif
4643diff --git a/src/torrent/utils/ranges.h b/src/torrent/utils/ranges.h
4644index e784b084..7b1f8cb0 100644
4645--- a/src/torrent/utils/ranges.h
4646+++ b/src/torrent/utils/ranges.h
4647@@ -40,7 +40,6 @@
4648 #include <algorithm>
4649 #include <vector>
4650
4651-// TODO: Use tr1 functional instead.
4652 #include <rak/functional.h>
4653
4654 namespace torrent {
4655diff --git a/src/torrent/utils/resume.cc b/src/torrent/utils/resume.cc
4656index 3f528c14..f8467d54 100644
4657--- a/src/torrent/utils/resume.cc
4658+++ b/src/torrent/utils/resume.cc
4659@@ -34,8 +34,6 @@
4660 // Skomakerveien 33
4661 // 3185 Skoppum, NORWAY
4662
4663-#define __STDC_FORMAT_MACROS
4664-
4665 #include "config.h"
4666
4667 #include <rak/file_stat.h>
4668diff --git a/src/torrent/utils/signal_bitfield.h b/src/torrent/utils/signal_bitfield.h
4669index b9f57a60..ffa336d2 100644
4670--- a/src/torrent/utils/signal_bitfield.h
4671+++ b/src/torrent/utils/signal_bitfield.h
4672@@ -37,7 +37,8 @@
4673 #ifndef LIBTORRENT_UTILS_SIGNAL_BITFIELD_H
4674 #define LIBTORRENT_UTILS_SIGNAL_BITFIELD_H
4675
4676-#include lt_tr1_functional
4677+#include <functional>
4678+
4679 #include <torrent/common.h>
4680
4681 namespace torrent {
4682diff --git a/src/torrent/utils/thread_base.h b/src/torrent/utils/thread_base.h
4683index bfd443ae..b92a98ba 100644
4684--- a/src/torrent/utils/thread_base.h
4685+++ b/src/torrent/utils/thread_base.h
4686@@ -37,11 +37,12 @@
4687 #ifndef LIBTORRENT_UTILS_THREAD_BASE_H
4688 #define LIBTORRENT_UTILS_THREAD_BASE_H
4689
4690+#include <functional>
4691 #include <pthread.h>
4692 #include <sys/types.h>
4693+
4694 #include <torrent/common.h>
4695 #include <torrent/utils/signal_bitfield.h>
4696-#include lt_tr1_functional
4697
4698 namespace torrent {
4699
4700diff --git a/src/utils/instrumentation.cc b/src/utils/instrumentation.cc
4701index 729b20e2..178d6a19 100644
4702--- a/src/utils/instrumentation.cc
4703+++ b/src/utils/instrumentation.cc
4704@@ -36,8 +36,6 @@
4705
4706 #include "config.h"
4707
4708-#define __STDC_FORMAT_MACROS
4709-
4710 #include "instrumentation.h"
4711
4712 namespace torrent {
4713diff --git a/src/utils/instrumentation.h b/src/utils/instrumentation.h
4714index 956429bf..11e77f6d 100644
4715--- a/src/utils/instrumentation.h
4716+++ b/src/utils/instrumentation.h
4717@@ -37,9 +37,8 @@
4718 #ifndef LIBTORRENT_UTILS_INSTRUMENTATION_H
4719 #define LIBTORRENT_UTILS_INSTRUMENTATION_H
4720
4721-#include lt_tr1_array
4722-
4723 #include <algorithm>
4724+#include <array>
4725
4726 #include "torrent/common.h"
4727 #include "torrent/utils/log.h"
4728diff --git a/src/utils/queue_buckets.h b/src/utils/queue_buckets.h
4729index de8584ff..b9174f27 100644
4730--- a/src/utils/queue_buckets.h
4731+++ b/src/utils/queue_buckets.h
4732@@ -38,9 +38,9 @@
4733 #define LIBTORRENT_QUEUE_BUCKETS_H
4734
4735 #include <algorithm>
4736+#include <array>
4737 #include <deque>
4738-#include lt_tr1_functional
4739-#include lt_tr1_array
4740+#include <functional>
4741
4742 namespace torrent {
4743
4744diff --git a/src/utils/sha_fast.h b/src/utils/sha_fast.h
4745index f7ce3b87..eb357864 100644
4746--- a/src/utils/sha_fast.h
4747+++ b/src/utils/sha_fast.h
4748@@ -41,7 +41,7 @@
4749 #ifndef _SHA_FAST_H_
4750 #define _SHA_FAST_H_
4751
4752-#include <inttypes.h>
4753+#include <cinttypes>
4754
4755 namespace torrent {
4756
4757diff --git a/test/Makefile.am b/test/Makefile.am
4758index d7a9d5b3..b60a86a6 100644
4759--- a/test/Makefile.am
4760+++ b/test/Makefile.am
4761@@ -18,6 +18,17 @@ LibTorrentTest_LDADD = \
4762 ../src/torrent/utils/libsub_torrentutils.la
4763
4764 LibTorrentTest_SOURCES = \
4765+ helpers/expect_fd.h \
4766+ helpers/expect_utils.h \
4767+ helpers/mock_compare.h \
4768+ helpers/mock_function.cc \
4769+ helpers/mock_function.h \
4770+ helpers/network.h \
4771+ helpers/progress_listener.cc \
4772+ helpers/progress_listener.h \
4773+ helpers/test_fixture.cc \
4774+ helpers/test_fixture.h \
4775+ \
4776 ../src/thread_disk.cc \
4777 ../src/thread_disk.h \
4778 \
4779@@ -31,22 +42,28 @@ LibTorrentTest_SOURCES = \
4780 data/hash_check_queue_test.h \
4781 data/hash_queue_test.cc \
4782 data/hash_queue_test.h \
4783+ \
4784+ net/test_socket_listen.cc \
4785+ net/test_socket_listen.h \
4786+ \
4787 protocol/test_request_list.cc \
4788 protocol/test_request_list.h \
4789 \
4790- torrent/net/test_socket_address_key.cc \
4791- torrent/net/test_socket_address_key.h \
4792+ torrent/net/test_address_info.cc \
4793+ torrent/net/test_address_info.h \
4794+ torrent/net/test_fd.cc \
4795+ torrent/net/test_fd.h \
4796+ torrent/net/test_socket_address.cc \
4797+ torrent/net/test_socket_address.h \
4798 \
4799 torrent/utils/log_test.cc \
4800 torrent/utils/log_test.h \
4801- torrent/utils/log_buffer_test.cc \
4802- torrent/utils/log_buffer_test.h \
4803- torrent/utils/net_test.cc \
4804- torrent/utils/net_test.h \
4805 torrent/utils/option_strings_test.cc \
4806 torrent/utils/option_strings_test.h \
4807 torrent/utils/test_extents.cc \
4808 torrent/utils/test_extents.h \
4809+ torrent/utils/test_log_buffer.cc \
4810+ torrent/utils/test_log_buffer.h \
4811 torrent/utils/test_queue_buckets.cc \
4812 torrent/utils/test_queue_buckets.h \
4813 torrent/utils/test_uri_parser.cc \
4814diff --git a/test/data/hash_check_queue_test.cc b/test/data/hash_check_queue_test.cc
4815index c6bdeaec..4b15245e 100644
4816--- a/test/data/hash_check_queue_test.cc
4817+++ b/test/data/hash_check_queue_test.cc
4818@@ -1,7 +1,7 @@
4819 #include "config.h"
4820
4821+#include <functional>
4822 #include <signal.h>
4823-#include lt_tr1_functional
4824
4825 #include "data/hash_queue_node.h"
4826 #include "utils/sha1.h"
4827diff --git a/test/data/hash_queue_test.cc b/test/data/hash_queue_test.cc
4828index 287c28e9..d7ce3ba8 100644
4829--- a/test/data/hash_queue_test.cc
4830+++ b/test/data/hash_queue_test.cc
4831@@ -1,7 +1,7 @@
4832 #include "config.h"
4833
4834+#include <functional>
4835 #include <signal.h>
4836-#include lt_tr1_functional
4837
4838 #include "data/hash_queue_node.h"
4839 #include "torrent/chunk_manager.h"
4840diff --git a/test/helpers/expect_fd.h b/test/helpers/expect_fd.h
4841new file mode 100644
4842index 00000000..178cbabc
4843--- /dev/null
4844+++ b/test/helpers/expect_fd.h
4845@@ -0,0 +1,107 @@
4846+#ifndef LIBTORRENT_HELPER_EXPECT_FD_H
4847+#define LIBTORRENT_HELPER_EXPECT_FD_H
4848+
4849+#include "helpers/mock_function.h"
4850+
4851+#include <fcntl.h>
4852+#include <torrent/event.h>
4853+#include <torrent/net/fd.h>
4854+#include <torrent/net/socket_address.h>
4855+
4856+typedef std::vector<torrent::sa_unique_ptr> sap_cache_type;
4857+
4858+inline const sockaddr*
4859+sap_cache_copy_addr_c_ptr(sap_cache_type& sap_cache, const torrent::c_sa_unique_ptr& sap, uint16_t port = 0) {
4860+ sap_cache.push_back(torrent::sap_copy_addr(sap, port));
4861+ return sap_cache.back().get();
4862+}
4863+
4864+inline void
4865+expect_event_open_re(int idx) {
4866+ mock_expect(&torrent::poll_event_open, mock_compare_map<torrent::Event>::begin_pointer + idx);
4867+ mock_expect(&torrent::poll_event_insert_read, mock_compare_map<torrent::Event>::begin_pointer + idx);
4868+ mock_expect(&torrent::poll_event_insert_error, mock_compare_map<torrent::Event>::begin_pointer + idx);
4869+}
4870+
4871+inline void
4872+expect_event_closed_fd(int idx, int fd) {
4873+ mock_expect(&torrent::fd__close, 0, fd);
4874+ mock_expect(&torrent::poll_event_closed, mock_compare_map<torrent::Event>::begin_pointer + idx);
4875+}
4876+
4877+inline void
4878+expect_fd_inet_tcp(int fd) {
4879+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4880+}
4881+
4882+inline void
4883+expect_fd_inet6_tcp(int fd) {
4884+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4885+}
4886+
4887+inline void
4888+expect_fd_inet_tcp_nonblock(int fd) {
4889+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4890+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
4891+}
4892+
4893+inline void
4894+expect_fd_inet6_tcp_nonblock(int fd) {
4895+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4896+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
4897+}
4898+
4899+inline void
4900+expect_fd_inet_tcp_nonblock_reuseaddr(int fd) {
4901+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4902+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
4903+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
4904+}
4905+
4906+inline void
4907+expect_fd_inet6_tcp_nonblock_reuseaddr(int fd) {
4908+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4909+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
4910+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
4911+}
4912+
4913+inline void
4914+expect_fd_inet6_tcp_v6only_nonblock(int fd) {
4915+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4916+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
4917+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
4918+}
4919+
4920+inline void
4921+expect_fd_inet6_tcp_v6only_nonblock_reuseaddr(int fd) {
4922+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
4923+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
4924+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
4925+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
4926+}
4927+
4928+inline void
4929+expect_fd_bind_connect(int fd, const torrent::c_sa_unique_ptr& bind_sap, const torrent::c_sa_unique_ptr& connect_sap) {
4930+ mock_expect(&torrent::fd__bind, 0, fd, bind_sap.get(), (socklen_t)torrent::sap_length(bind_sap));
4931+ mock_expect(&torrent::fd__connect, 0, fd, connect_sap.get(), (socklen_t)torrent::sap_length(connect_sap));
4932+}
4933+
4934+inline void
4935+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) {
4936+ do {
4937+ mock_expect(&torrent::fd__bind, -1, fd, sap_cache_copy_addr_c_ptr(sap_cache, sap, first_port), (socklen_t)torrent::sap_length(sap));
4938+ } while (first_port++ != last_port);
4939+}
4940+
4941+inline void
4942+expect_fd_bind_listen(int fd, const torrent::c_sa_unique_ptr& sap) {
4943+ mock_expect(&torrent::fd__bind, 0, fd, sap.get(), (socklen_t)torrent::sap_length(sap));
4944+ mock_expect(&torrent::fd__listen, 0, fd, SOMAXCONN);
4945+}
4946+
4947+inline void
4948+expect_fd_connect(int fd, const torrent::c_sa_unique_ptr& sap) {
4949+ mock_expect(&torrent::fd__connect, 0, fd, sap.get(), (socklen_t)torrent::sap_length(sap));
4950+}
4951+
4952+#endif
4953diff --git a/test/helpers/expect_utils.h b/test/helpers/expect_utils.h
4954new file mode 100644
4955index 00000000..c84a11e0
4956--- /dev/null
4957+++ b/test/helpers/expect_utils.h
4958@@ -0,0 +1,13 @@
4959+#ifndef LIBTORRENT_HELPER_EXPECT_UTILS_H
4960+#define LIBTORRENT_HELPER_EXPECT_UTILS_H
4961+
4962+#include "helpers/mock_function.h"
4963+
4964+#include <torrent/utils/random.h>
4965+
4966+inline void
4967+expect_random_uniform_uint16(uint16_t result, uint16_t first, uint16_t last) {
4968+ mock_expect(&torrent::random_uniform_uint16, result, first, last);
4969+}
4970+
4971+#endif
4972diff --git a/test/helpers/mock_compare.h b/test/helpers/mock_compare.h
4973new file mode 100644
4974index 00000000..3ea90305
4975--- /dev/null
4976+++ b/test/helpers/mock_compare.h
4977@@ -0,0 +1,96 @@
4978+#ifndef LIBTORRENT_HELPERS_MOCK_COMPARE_H
4979+#define LIBTORRENT_HELPERS_MOCK_COMPARE_H
4980+
4981+#include <algorithm>
4982+#include <type_traits>
4983+#include <torrent/event.h>
4984+#include <torrent/net/socket_address.h>
4985+
4986+// Compare arguments to mock functions with what is expected. The lhs
4987+// are the expected arguments, rhs are the ones called with.
4988+
4989+template <typename Arg>
4990+inline bool mock_compare_arg(Arg lhs, Arg rhs) { return lhs == rhs; }
4991+
4992+template <int I, typename A, typename... Args>
4993+typename std::enable_if<I == 1, int>::type
4994+mock_compare_tuple(const std::tuple<A, Args...>& lhs, const std::tuple<Args...>& rhs) {
4995+ return mock_compare_arg(std::get<I>(lhs), std::get<I - 1>(rhs)) ? 0 : 1;
4996+}
4997+
4998+template <int I, typename A, typename... Args>
4999+typename std::enable_if<1 < I, int>::type
5000+mock_compare_tuple(const std::tuple<A, Args...>& lhs, const std::tuple<Args...>& rhs) {
5001+ auto res = mock_compare_tuple<I - 1>(lhs, rhs);
5002+
5003+ if (res != 0)
5004+ return res;
5005+
5006+ return mock_compare_arg(std::get<I>(lhs), std::get<I - 1>(rhs)) ? 0 : I;
5007+}
5008+
5009+//template <typename T, typename std::enable_if<!std::is_const<T>::value, int>::type = 0>
5010+template <typename T>
5011+struct mock_compare_map {
5012+ typedef std::map<const T*, const T*> values_type;
5013+
5014+ constexpr static T* begin_pointer = reinterpret_cast<T*>(0x1000);
5015+ constexpr static T* end_pointer = reinterpret_cast<T*>(0x2000);
5016+
5017+ static bool is_key(const T* k) {
5018+ return k >= begin_pointer && k < end_pointer;
5019+ }
5020+
5021+ static bool has_key(const T* k) {
5022+ return values.find(k) != values.end();
5023+ }
5024+
5025+ static bool has_value(const T* v) {
5026+ return std::find_if(values.begin(), values.end(), [v](typename values_type::value_type& kv) { return v == kv.second; }) != values.end();
5027+ }
5028+
5029+ static const T* get(const T* k) {
5030+ auto itr = values.find(k);
5031+ CPPUNIT_ASSERT_MESSAGE("mock_compare_map get failed, not inserted", itr != values.end());
5032+ return itr->second;
5033+ }
5034+
5035+ static values_type values;
5036+};
5037+
5038+template<typename T>
5039+typename mock_compare_map<T>::values_type mock_compare_map<T>::values;
5040+
5041+template<typename T>
5042+void mock_compare_add(T* v) {
5043+ mock_compare_map<T>::add_value(v);
5044+}
5045+
5046+//
5047+// Specialize:
5048+//
5049+
5050+template <>
5051+inline bool mock_compare_arg<sockaddr*>(sockaddr* lhs, sockaddr* rhs) {
5052+ return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs);
5053+}
5054+template <>
5055+inline bool mock_compare_arg<const sockaddr*>(const sockaddr* lhs, const sockaddr* rhs) {
5056+ return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs);
5057+}
5058+
5059+template <>
5060+inline bool mock_compare_arg<torrent::Event*>(torrent::Event* lhs, torrent::Event* rhs) {
5061+ if (mock_compare_map<torrent::Event>::is_key(lhs)) {
5062+ if (!mock_compare_map<torrent::Event>::has_value(rhs)) {
5063+ mock_compare_map<torrent::Event>::values[lhs] = rhs;
5064+ return true;
5065+ }
5066+
5067+ return mock_compare_map<torrent::Event>::has_key(lhs) && mock_compare_map<torrent::Event>::get(lhs) == rhs;
5068+ }
5069+
5070+ return lhs == rhs;
5071+}
5072+
5073+#endif
5074diff --git a/test/helpers/mock_function.cc b/test/helpers/mock_function.cc
5075new file mode 100644
5076index 00000000..83e81551
5077--- /dev/null
5078+++ b/test/helpers/mock_function.cc
5079@@ -0,0 +1,170 @@
5080+#include "config.h"
5081+
5082+#include "mock_function.h"
5083+
5084+#include <fcntl.h>
5085+#include <iostream>
5086+#include <torrent/event.h>
5087+#include <torrent/net/socket_address.h>
5088+#include <torrent/net/fd.h>
5089+#include <torrent/utils/log.h>
5090+#include <torrent/utils/random.h>
5091+
5092+#define MOCK_CLEANUP_MAP(MOCK_FUNC) \
5093+ CPPUNIT_ASSERT_MESSAGE("expected mock function calls not completed for '" #MOCK_FUNC "'", mock_cleanup_map(&MOCK_FUNC) || ignore_assert);
5094+#define MOCK_LOG(log_fmt, ...) \
5095+ lt_log_print(torrent::LOG_MOCK_CALLS, "%s: " log_fmt, __func__, __VA_ARGS__);
5096+
5097+void
5098+mock_clear(bool ignore_assert) {
5099+ MOCK_CLEANUP_MAP(torrent::fd__accept);
5100+ MOCK_CLEANUP_MAP(torrent::fd__bind);
5101+ MOCK_CLEANUP_MAP(torrent::fd__close);
5102+ MOCK_CLEANUP_MAP(torrent::fd__connect);
5103+ MOCK_CLEANUP_MAP(torrent::fd__fcntl_int);
5104+ MOCK_CLEANUP_MAP(torrent::fd__listen);
5105+ MOCK_CLEANUP_MAP(torrent::fd__setsockopt_int);
5106+ MOCK_CLEANUP_MAP(torrent::fd__socket);
5107+
5108+ MOCK_CLEANUP_MAP(torrent::poll_event_open);
5109+ MOCK_CLEANUP_MAP(torrent::poll_event_close);
5110+ MOCK_CLEANUP_MAP(torrent::poll_event_closed);
5111+ MOCK_CLEANUP_MAP(torrent::poll_event_insert_read);
5112+ MOCK_CLEANUP_MAP(torrent::poll_event_insert_write);
5113+ MOCK_CLEANUP_MAP(torrent::poll_event_insert_error);
5114+ MOCK_CLEANUP_MAP(torrent::poll_event_remove_read);
5115+ MOCK_CLEANUP_MAP(torrent::poll_event_remove_write);
5116+ MOCK_CLEANUP_MAP(torrent::poll_event_remove_error);
5117+
5118+ MOCK_CLEANUP_MAP(torrent::random_uniform_uint16);
5119+ MOCK_CLEANUP_MAP(torrent::random_uniform_uint32);
5120+
5121+ mock_compare_map<torrent::Event>::values.clear();
5122+};
5123+
5124+void mock_init() {
5125+ log_add_group_output(torrent::LOG_MOCK_CALLS, "test_output");
5126+ mock_clear(true);
5127+}
5128+
5129+void mock_cleanup() {
5130+ mock_clear(false);
5131+}
5132+
5133+namespace torrent {
5134+
5135+//
5136+// Mock functions for 'torrent/net/fd.h':
5137+//
5138+
5139+int fd__accept(int socket, sockaddr *address, socklen_t *address_len) {
5140+ MOCK_LOG("entry socket:%i address:%s address_len:%u",
5141+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len));
5142+ auto ret = mock_call<int>(__func__, &torrent::fd__accept, socket, address, address_len);
5143+ MOCK_LOG("exit socket:%i address:%s address_len:%u",
5144+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len));
5145+ return ret;
5146+}
5147+
5148+int fd__bind(int socket, const sockaddr *address, socklen_t address_len) {
5149+ MOCK_LOG("socket:%i address:%s address_len:%u",
5150+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len);
5151+ return mock_call<int>(__func__, &torrent::fd__bind, socket, address, address_len);
5152+}
5153+
5154+int fd__close(int fildes) {
5155+ MOCK_LOG("filedes:%i", fildes);
5156+ return mock_call<int>(__func__, &torrent::fd__close, fildes);
5157+}
5158+
5159+int fd__connect(int socket, const sockaddr *address, socklen_t address_len) {
5160+ MOCK_LOG("socket:%i address:%s address_len:%u",
5161+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len);
5162+ return mock_call<int>(__func__, &torrent::fd__connect, socket, address, address_len);
5163+}
5164+
5165+int fd__fcntl_int(int fildes, int cmd, int arg) {
5166+ MOCK_LOG("filedes:%i cmd:%i arg:%i", fildes, cmd, arg);
5167+ return mock_call<int>(__func__, &torrent::fd__fcntl_int, fildes, cmd, arg);
5168+}
5169+
5170+int fd__listen(int socket, int backlog) {
5171+ MOCK_LOG("socket:%i backlog:%i", socket, backlog);
5172+ return mock_call<int>(__func__, &torrent::fd__listen, socket, backlog);
5173+}
5174+
5175+int fd__setsockopt_int(int socket, int level, int option_name, int option_value) {
5176+ MOCK_LOG("socket:%i level:%i option_name:%i option_value:%i",
5177+ socket, level, option_name, option_value);
5178+ return mock_call<int>(__func__, &torrent::fd__setsockopt_int, socket, level, option_name, option_value);
5179+}
5180+
5181+int fd__socket(int domain, int type, int protocol) {
5182+ MOCK_LOG("domain:%i type:%i protocol:%i", domain, type, protocol);
5183+ return mock_call<int>(__func__, &torrent::fd__socket, domain, type, protocol);
5184+}
5185+
5186+//
5187+// Mock functions for 'torrent/event.h':
5188+//
5189+
5190+void poll_event_open(Event* event) {
5191+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5192+ return mock_call<void>(__func__, &torrent::poll_event_open, event);
5193+}
5194+
5195+void poll_event_close(Event* event) {
5196+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5197+ return mock_call<void>(__func__, &torrent::poll_event_close, event);
5198+}
5199+
5200+void poll_event_closed(Event* event) {
5201+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5202+ return mock_call<void>(__func__, &torrent::poll_event_closed, event);
5203+}
5204+
5205+void poll_event_insert_read(Event* event) {
5206+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5207+ return mock_call<void>(__func__, &torrent::poll_event_insert_read, event);
5208+}
5209+
5210+void poll_event_insert_write(Event* event) {
5211+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5212+ return mock_call<void>(__func__, &torrent::poll_event_insert_write, event);
5213+}
5214+
5215+void poll_event_insert_error(Event* event) {
5216+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5217+ return mock_call<void>(__func__, &torrent::poll_event_insert_error, event);
5218+}
5219+
5220+void poll_event_remove_read(Event* event) {
5221+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5222+ return mock_call<void>(__func__, &torrent::poll_event_remove_read, event);
5223+}
5224+
5225+void poll_event_remove_write(Event* event) {
5226+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5227+ return mock_call<void>(__func__, &torrent::poll_event_remove_write, event);
5228+}
5229+
5230+void poll_event_remove_error(Event* event) {
5231+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
5232+ return mock_call<void>(__func__, &torrent::poll_event_remove_error, event);
5233+}
5234+
5235+//
5236+// Mock functions for 'torrent/utils/random.h':
5237+//
5238+
5239+uint16_t random_uniform_uint16(uint16_t min, uint16_t max) {
5240+ MOCK_LOG("min:%" PRIu16 " max:%" PRIu16, min, max);
5241+ return mock_call<uint16_t>(__func__, &torrent::random_uniform_uint16, min, max);
5242+}
5243+
5244+uint32_t random_uniform_uint32(uint32_t min, uint32_t max) {
5245+ MOCK_LOG("min:%" PRIu32 " max:%" PRIu32, min, max);
5246+ return mock_call<uint32_t>(__func__, &torrent::random_uniform_uint32, min, max);
5247+}
5248+
5249+}
5250diff --git a/test/helpers/mock_function.h b/test/helpers/mock_function.h
5251new file mode 100644
5252index 00000000..6c194137
5253--- /dev/null
5254+++ b/test/helpers/mock_function.h
5255@@ -0,0 +1,133 @@
5256+#ifndef LIBTORRENT_HELPERS_MOCK_FUNCTION_H
5257+#define LIBTORRENT_HELPERS_MOCK_FUNCTION_H
5258+
5259+#include <functional>
5260+#include <map>
5261+#include <string>
5262+#include <tuple>
5263+#include <type_traits>
5264+#include <utility>
5265+#include <cppunit/extensions/HelperMacros.h>
5266+
5267+#include "helpers/mock_compare.h"
5268+
5269+template<typename R, typename... Args>
5270+struct mock_function_map {
5271+ typedef std::tuple<R, Args...> call_type;
5272+ typedef std::vector<call_type> call_list_type;
5273+ typedef std::map<void*, call_list_type> func_map_type;
5274+
5275+ typedef std::function<R (Args...)> function_type;
5276+ typedef std::map<void*, function_type> redirect_map_type;
5277+
5278+ static func_map_type functions;
5279+ static redirect_map_type redirects;
5280+
5281+ static bool cleanup(void* fn) {
5282+ redirects.erase(fn);
5283+ return functions.erase(fn) == 0;
5284+ }
5285+
5286+ static R ret_erase(void* fn) {
5287+ auto itr = functions.find(fn);
5288+ auto ret = std::get<0>(itr->second.front());
5289+ itr->second.erase(itr->second.begin());
5290+
5291+ if (itr->second.empty())
5292+ functions.erase(itr);
5293+
5294+ return ret;
5295+ }
5296+};
5297+
5298+template<typename R, typename... Args>
5299+typename mock_function_map<R, Args...>::func_map_type mock_function_map<R, Args...>::functions;
5300+template<typename R, typename... Args>
5301+typename mock_function_map<R, Args...>::redirect_map_type mock_function_map<R, Args...>::redirects;
5302+
5303+struct mock_void {};
5304+
5305+template<typename R, typename... Args>
5306+struct mock_function_type {
5307+ typedef mock_function_map<R, Args...> type;
5308+
5309+ static int compare_expected(typename type::call_type lhs, Args... rhs) {
5310+ return mock_compare_tuple<sizeof...(Args)>(lhs, std::make_tuple(rhs...));
5311+ }
5312+
5313+ static R ret_erase(void* fn) { return type::ret_erase(fn); }
5314+ static bool has_redirect(void* fn) { return type::redirects.find(fn) != type::redirects.end(); }
5315+ static R call_redirect(void* fn, Args... args) { return type::redirects.find(fn)->second(args...); }
5316+};
5317+
5318+template<typename... Args>
5319+struct mock_function_type<void, Args...> {
5320+ typedef mock_function_map<mock_void, Args...> type;
5321+
5322+ static int compare_expected(typename type::call_type lhs, Args... rhs) {
5323+ return mock_compare_tuple<sizeof...(Args)>(lhs, std::make_tuple(rhs...));
5324+ }
5325+
5326+ static void ret_erase(void* fn) { type::ret_erase(fn); }
5327+ static bool has_redirect(void* fn) { return type::redirects.find(fn) != type::redirects.end(); }
5328+ static void call_redirect(void* fn, Args... args) { type::redirects.find(fn)->second(args...); }
5329+};
5330+
5331+void mock_init();
5332+void mock_cleanup();
5333+
5334+template<typename R, typename... Args>
5335+bool
5336+mock_cleanup_map(R fn[[gnu::unused]](Args...)) {
5337+ return mock_function_type<R, Args...>::type::cleanup(reinterpret_cast<void*>(fn));
5338+}
5339+
5340+template<typename R, typename... Args>
5341+void
5342+mock_expect(R fn(Args...), R ret, Args... args) {
5343+ typedef mock_function_map<R, Args...> mock_map;
5344+ mock_map::functions[reinterpret_cast<void*>(fn)].push_back(std::tuple<R, Args...>(ret, args...));
5345+}
5346+
5347+template<typename... Args>
5348+void
5349+mock_expect(void fn(Args...), Args... args) {
5350+ typedef mock_function_map<mock_void, Args...> mock_map;
5351+ mock_map::functions[reinterpret_cast<void*>(fn)].push_back(std::tuple<mock_void, Args...>(mock_void(), args...));
5352+}
5353+
5354+template<typename R, typename... Args>
5355+void
5356+mock_redirect(R fn(Args...), std::function<R (Args...)> func) {
5357+ typedef mock_function_map<R, Args...> mock_map;
5358+ mock_map::redirects[reinterpret_cast<void*>(fn)] = func;
5359+}
5360+
5361+template<typename R, typename... Args>
5362+auto
5363+mock_call_direct(std::string name, R fn(Args...), Args... args) -> decltype(fn(args...)) {
5364+ typedef mock_function_type<R, Args...> mock_type;
5365+
5366+ auto itr = mock_type::type::functions.find(reinterpret_cast<void*>(fn));
5367+ CPPUNIT_ASSERT_MESSAGE(("mock_call expected function calls exhausted by '" + name + "'").c_str(),
5368+ itr != mock_type::type::functions.end());
5369+
5370+ auto mismatch_arg = mock_type::compare_expected(itr->second.front(), args...);
5371+ CPPUNIT_ASSERT_MESSAGE(("mock_call expected function call argument " + std::to_string(mismatch_arg) + " mismatch for '" + name + "'").c_str(),
5372+ mismatch_arg == 0);
5373+
5374+ return mock_type::ret_erase(reinterpret_cast<void*>(fn));
5375+}
5376+
5377+template<typename R, typename... Args>
5378+auto
5379+mock_call(std::string name, R fn(Args...), Args... args) -> decltype(fn(args...)) {
5380+ typedef mock_function_type<R, Args...> mock_type;
5381+
5382+ if (mock_type::has_redirect(reinterpret_cast<void*>(fn)))
5383+ return mock_type::call_redirect(reinterpret_cast<void*>(fn), args...);
5384+
5385+ return mock_call_direct(name, fn, args...);
5386+}
5387+
5388+#endif
5389diff --git a/test/helpers/network.h b/test/helpers/network.h
5390new file mode 100644
5391index 00000000..6cf2f870
5392--- /dev/null
5393+++ b/test/helpers/network.h
5394@@ -0,0 +1,182 @@
5395+#ifndef LIBTORRENT_HELPER_NETWORK_H
5396+#define LIBTORRENT_HELPER_NETWORK_H
5397+
5398+#include <functional>
5399+#include <string>
5400+#include <cppunit/extensions/HelperMacros.h>
5401+
5402+#include "torrent/net/address_info.h"
5403+
5404+//
5405+// Socket addresses
5406+//
5407+
5408+#define TEST_DEFAULT_SA \
5409+ auto sin_any = wrap_ai_get_first_sa("0.0.0.0"); \
5410+ auto sin_any_5000 = wrap_ai_get_first_sa("0.0.0.0", "5000"); \
5411+ auto sin_any_5005 = wrap_ai_get_first_sa("0.0.0.0", "5005"); \
5412+ auto sin_bc = wrap_ai_get_first_sa("255.255.255.255"); \
5413+ auto sin_bc_5000 = wrap_ai_get_first_sa("255.255.255.255", "5000"); \
5414+ auto sin_bnd = wrap_ai_get_first_sa("123.123.123.123"); \
5415+ auto sin_1 = wrap_ai_get_first_sa("1.2.3.4"); \
5416+ auto sin_1_5000 = wrap_ai_get_first_sa("1.2.3.4", "5000"); \
5417+ auto sin_1_5005 = wrap_ai_get_first_sa("1.2.3.4", "5005"); \
5418+ auto sin_1_5100 = wrap_ai_get_first_sa("1.2.3.4", "5100"); \
5419+ auto sin_2 = wrap_ai_get_first_sa("4.3.2.1"); \
5420+ auto sin_2_5000 = wrap_ai_get_first_sa("4.3.2.1", "5000"); \
5421+ auto sin_2_5100 = wrap_ai_get_first_sa("4.3.2.1", "5100"); \
5422+ \
5423+ auto sin6_any = wrap_ai_get_first_sa("::"); \
5424+ auto sin6_any_5000 = wrap_ai_get_first_sa("::", "5000"); \
5425+ auto sin6_any_5005 = wrap_ai_get_first_sa("::", "5005"); \
5426+ auto sin6_bnd = wrap_ai_get_first_sa("ff01::123"); \
5427+ auto sin6_1 = wrap_ai_get_first_sa("ff01::1"); \
5428+ auto sin6_1_5000 = wrap_ai_get_first_sa("ff01::1", "5000"); \
5429+ auto sin6_1_5005 = wrap_ai_get_first_sa("ff01::1", "5005"); \
5430+ auto sin6_1_5100 = wrap_ai_get_first_sa("ff01::1", "5100"); \
5431+ auto sin6_2 = wrap_ai_get_first_sa("ff02::2"); \
5432+ auto sin6_2_5000 = wrap_ai_get_first_sa("ff02::2", "5000"); \
5433+ auto sin6_2_5100 = wrap_ai_get_first_sa("ff02::2", "5100"); \
5434+ auto sin6_v4_1 = wrap_ai_get_first_sa("::ffff:1.2.3.4"); \
5435+ auto sin6_v4_1_5000 = wrap_ai_get_first_sa("::ffff:1.2.3.4", "5000"); \
5436+ auto sin6_v4_any = wrap_ai_get_first_sa("::ffff:0.0.0.0"); \
5437+ auto sin6_v4_any_5000 = wrap_ai_get_first_sa("::ffff:0.0.0.0", "5000"); \
5438+ auto sin6_v4_bc = wrap_ai_get_first_sa("::ffff:255.255.255.255"); \
5439+ auto sin6_v4_bc_5000 = wrap_ai_get_first_sa("::ffff:255.255.255.255", "5000"); \
5440+ auto sin6_v4_bnd = wrap_ai_get_first_sa("::ffff:123.123.123.123"); \
5441+ \
5442+ auto c_sin_any = wrap_ai_get_first_c_sa("0.0.0.0"); \
5443+ auto c_sin_any_5000 = wrap_ai_get_first_c_sa("0.0.0.0", "5000"); \
5444+ auto c_sin_any_5005 = wrap_ai_get_first_c_sa("0.0.0.0", "5005"); \
5445+ auto c_sin_any_5010 = wrap_ai_get_first_c_sa("0.0.0.0", "5010"); \
5446+ auto c_sin_any_6881 = wrap_ai_get_first_c_sa("0.0.0.0", "6881"); \
5447+ auto c_sin_any_6900 = wrap_ai_get_first_c_sa("0.0.0.0", "6900"); \
5448+ auto c_sin_any_6999 = wrap_ai_get_first_c_sa("0.0.0.0", "6999"); \
5449+ auto c_sin_bc = wrap_ai_get_first_c_sa("255.255.255.255"); \
5450+ auto c_sin_bc_5000 = wrap_ai_get_first_c_sa("255.255.255.255", "5000"); \
5451+ auto c_sin_bnd = wrap_ai_get_first_c_sa("123.123.123.123"); \
5452+ auto c_sin_bnd_5000 = wrap_ai_get_first_c_sa("123.123.123.123", "5000"); \
5453+ auto c_sin_bnd_6881 = wrap_ai_get_first_c_sa("123.123.123.123", "6881"); \
5454+ auto c_sin_bnd_6900 = wrap_ai_get_first_c_sa("123.123.123.123", "6900"); \
5455+ auto c_sin_bnd_6999 = wrap_ai_get_first_c_sa("123.123.123.123", "6999"); \
5456+ auto c_sin_1 = wrap_ai_get_first_c_sa("1.2.3.4"); \
5457+ auto c_sin_1_5000 = wrap_ai_get_first_c_sa("1.2.3.4", "5000"); \
5458+ auto c_sin_1_5005 = wrap_ai_get_first_c_sa("1.2.3.4", "5005"); \
5459+ auto c_sin_1_5010 = wrap_ai_get_first_c_sa("1.2.3.4", "5010"); \
5460+ auto c_sin_1_6881 = wrap_ai_get_first_c_sa("1.2.3.4", "6881"); \
5461+ auto c_sin_1_6900 = wrap_ai_get_first_c_sa("1.2.3.4", "6900"); \
5462+ auto c_sin_1_6999 = wrap_ai_get_first_c_sa("1.2.3.4", "6999"); \
5463+ auto c_sin_2 = wrap_ai_get_first_c_sa("4.3.2.1"); \
5464+ auto c_sin_2_5000 = wrap_ai_get_first_c_sa("4.3.2.1", "5000"); \
5465+ auto c_sin_2_5100 = wrap_ai_get_first_c_sa("4.3.2.1", "5100"); \
5466+ \
5467+ auto c_sin6_any = wrap_ai_get_first_c_sa("::"); \
5468+ auto c_sin6_any_5000 = wrap_ai_get_first_c_sa("::", "5000"); \
5469+ auto c_sin6_any_5005 = wrap_ai_get_first_c_sa("::", "5005"); \
5470+ auto c_sin6_any_5010 = wrap_ai_get_first_c_sa("::", "5010"); \
5471+ auto c_sin6_any_6881 = wrap_ai_get_first_c_sa("::", "6881"); \
5472+ auto c_sin6_any_6900 = wrap_ai_get_first_c_sa("::", "6900"); \
5473+ auto c_sin6_any_6999 = wrap_ai_get_first_c_sa("::", "6999"); \
5474+ auto c_sin6_bnd = wrap_ai_get_first_c_sa("ff01::123"); \
5475+ auto c_sin6_bnd_5000 = wrap_ai_get_first_c_sa("ff01::123", "5000"); \
5476+ auto c_sin6_bnd_6881 = wrap_ai_get_first_c_sa("ff01::123", "6881"); \
5477+ auto c_sin6_bnd_6900 = wrap_ai_get_first_c_sa("ff01::123", "6900"); \
5478+ auto c_sin6_bnd_6999 = wrap_ai_get_first_c_sa("ff01::123", "6999"); \
5479+ auto c_sin6_v4_1_5000 = wrap_ai_get_first_c_sa("::ffff:1.2.3.4", "5000"); \
5480+ auto c_sin6_1 = wrap_ai_get_first_c_sa("ff01::1"); \
5481+ auto c_sin6_1_5000 = wrap_ai_get_first_c_sa("ff01::1", "5000"); \
5482+ auto c_sin6_1_5005 = wrap_ai_get_first_c_sa("ff01::1", "5005"); \
5483+ auto c_sin6_1_5010 = wrap_ai_get_first_c_sa("ff01::1", "5010"); \
5484+ auto c_sin6_1_5100 = wrap_ai_get_first_c_sa("ff01::1", "5100"); \
5485+ auto c_sin6_1_6881 = wrap_ai_get_first_c_sa("ff01::1", "6881"); \
5486+ auto c_sin6_1_6900 = wrap_ai_get_first_c_sa("ff01::1", "6900"); \
5487+ auto c_sin6_1_6999 = wrap_ai_get_first_c_sa("ff01::1", "6999"); \
5488+ auto c_sin6_2 = wrap_ai_get_first_c_sa("ff02::2"); \
5489+ auto c_sin6_2_5000 = wrap_ai_get_first_c_sa("ff02::2", "5000"); \
5490+ auto c_sin6_2_5100 = wrap_ai_get_first_c_sa("ff02::2", "5100");
5491+
5492+inline bool
5493+compare_sin6_addr(in6_addr lhs, in6_addr rhs) {
5494+ return std::equal(lhs.s6_addr, lhs.s6_addr + 16, rhs.s6_addr);
5495+}
5496+
5497+inline bool
5498+compare_listen_result(const torrent::listen_result_type& lhs, int rhs_fd, const torrent::c_sa_unique_ptr& rhs_sap) {
5499+ return lhs.fd == rhs_fd &&
5500+ ((lhs.address && rhs_sap) || ((lhs.address && rhs_sap) && torrent::sap_equal(lhs.address, rhs_sap)));
5501+}
5502+
5503+inline torrent::sa_unique_ptr
5504+wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) {
5505+ auto sa = torrent::ai_get_first_sa(nodename, servname, hints);
5506+
5507+ CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
5508+ sa != nullptr);
5509+ return sa;
5510+}
5511+
5512+inline torrent::c_sa_unique_ptr
5513+wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) {
5514+ auto sa = torrent::ai_get_first_sa(nodename, servname, hints);
5515+
5516+ CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
5517+ sa != nullptr);
5518+ return torrent::c_sa_unique_ptr(sa.release());
5519+}
5520+
5521+//
5522+// Address info tests:
5523+//
5524+
5525+typedef std::function<int (torrent::ai_unique_ptr&)> test_ai_ref;
5526+
5527+enum ai_flags_enum : int {
5528+ aif_none = 0x0,
5529+ aif_inet = 0x1,
5530+ aif_inet6 = 0x2,
5531+ aif_any = 0x4,
5532+};
5533+
5534+constexpr ai_flags_enum operator | (ai_flags_enum a, ai_flags_enum b) {
5535+ return static_cast<ai_flags_enum>(static_cast<int>(a) | static_cast<int>(b));
5536+}
5537+
5538+template <ai_flags_enum ai_flags>
5539+inline bool
5540+test_valid_ai_ref(test_ai_ref ftor, uint16_t port = 0) {
5541+ torrent::ai_unique_ptr ai;
5542+
5543+ if (int err = ftor(ai)) {
5544+ std::cout << std::endl << "valid_ai_ref got error '" << gai_strerror(err) << "'" << std::endl;
5545+ return false;
5546+ }
5547+
5548+ if ((ai_flags & aif_inet) && !torrent::sa_is_inet(ai->ai_addr))
5549+ return false;
5550+
5551+ if ((ai_flags & aif_inet6) && !torrent::sa_is_inet6(ai->ai_addr))
5552+ return false;
5553+
5554+ if (!!(ai_flags & aif_any) == !torrent::sa_is_any(ai->ai_addr))
5555+ return false;
5556+
5557+ if (torrent::sa_port(ai->ai_addr) != port)
5558+ return false;
5559+
5560+ return true;
5561+}
5562+
5563+inline bool
5564+test_valid_ai_ref_err(test_ai_ref ftor, int expect_err) {
5565+ torrent::ai_unique_ptr ai;
5566+ int err = ftor(ai);
5567+
5568+ if (err != expect_err) {
5569+ std::cout << std::endl << "ai_ref_err got wrong error, expected '" << gai_strerror(expect_err) << "', got '" << gai_strerror(err) << "'" << std::endl;
5570+ return false;
5571+ }
5572+
5573+ return true;
5574+}
5575+
5576+#endif
5577diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc
5578new file mode 100644
5579index 00000000..02803ffc
5580--- /dev/null
5581+++ b/test/helpers/progress_listener.cc
5582@@ -0,0 +1,63 @@
5583+#include "config.h"
5584+
5585+#include "progress_listener.h"
5586+
5587+#include <algorithm>
5588+#include <iostream>
5589+#include <iterator>
5590+#include <numeric>
5591+#include <stdexcept>
5592+#include "torrent/utils/log.h"
5593+#include "torrent/utils/log_buffer.h"
5594+
5595+static std::string
5596+get_test_path(const test_list_type& tl) {
5597+ if (tl.size() < 2)
5598+ return "";
5599+
5600+ return std::accumulate(std::next(tl.begin()), std::prev(tl.end()), std::string(), [](std::string result, CppUnit::Test* test) {
5601+ return std::move(result) + test->getName() + "::";
5602+ });
5603+}
5604+
5605+void
5606+progress_listener::startTest(CppUnit::Test *test) {
5607+ std::cout << get_test_path(m_test_path) << test->getName() << std::flush;
5608+
5609+ torrent::log_cleanup();
5610+
5611+ m_last_test_failed = false;
5612+ m_current_log_buffer = torrent::log_open_log_buffer("test_output");
5613+}
5614+
5615+void
5616+progress_listener::addFailure(const CppUnit::TestFailure &failure) {
5617+ // AddFailure is called for parent test suits, so only deal with leafs.
5618+ if (m_current_log_buffer == nullptr)
5619+ return;
5620+
5621+ std::cout << " : " << (failure.isError() ? "error" : "assertion");
5622+
5623+ m_last_test_failed = true;
5624+ m_failures.push_back(std::move(failure_type{failure.failedTestName(), std::move(m_current_log_buffer)}));
5625+}
5626+
5627+void
5628+progress_listener::endTest(CppUnit::Test *test) {
5629+ std::cout << (m_last_test_failed ? "" : " : OK") << std::endl;
5630+
5631+ m_current_log_buffer.reset();
5632+ torrent::log_cleanup();
5633+}
5634+
5635+void
5636+progress_listener::startSuite(CppUnit::Test *suite) {
5637+ m_test_path.push_back(suite);
5638+
5639+ std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl;
5640+}
5641+
5642+void
5643+progress_listener::endSuite(CppUnit::Test *suite) {
5644+ m_test_path.pop_back();
5645+}
5646diff --git a/test/helpers/progress_listener.h b/test/helpers/progress_listener.h
5647new file mode 100644
5648index 00000000..18fb8faa
5649--- /dev/null
5650+++ b/test/helpers/progress_listener.h
5651@@ -0,0 +1,47 @@
5652+#include <memory>
5653+#include <vector>
5654+#include <cppunit/Test.h>
5655+#include <cppunit/TestFailure.h>
5656+#include <cppunit/TestListener.h>
5657+
5658+#include "torrent/utils/log_buffer.h"
5659+
5660+struct failure_type {
5661+ std::string name;
5662+ torrent::log_buffer_ptr log;
5663+};
5664+
5665+typedef std::unique_ptr<CppUnit::TestFailure> test_failure_ptr;
5666+typedef std::vector<CppUnit::Test*> test_list_type;
5667+typedef std::vector<failure_type> failure_list_type;
5668+
5669+class progress_listener : public CppUnit::TestListener {
5670+public:
5671+ progress_listener() : m_last_test_failed(false) {}
5672+
5673+ void startTest(CppUnit::Test *test) override;
5674+ void addFailure(const CppUnit::TestFailure &failure) override;
5675+ void endTest(CppUnit::Test *test) override;
5676+
5677+ void startSuite(CppUnit::Test *suite) override;
5678+ void endSuite(CppUnit::Test *suite) override;
5679+
5680+ //Called by a TestRunner before running the test.
5681+ // void startTestRun(CppUnit::Test *test, CppUnit::TestResult *event_manager) override;
5682+
5683+ // Called by a TestRunner after running the test.
5684+ // void endTestRun(CppUnit::Test *test, CppUnit::TestResult *event_manager) override;
5685+
5686+ const failure_list_type& failures() { return m_failures; }
5687+ failure_list_type&& move_failures() { return std::move(m_failures); }
5688+
5689+private:
5690+ progress_listener(const progress_listener& rhs) = delete;
5691+ void operator =(const progress_listener& rhs) = delete;
5692+
5693+ test_list_type m_test_path;
5694+ failure_list_type m_failures;
5695+ bool m_last_test_failed;
5696+
5697+ torrent::log_buffer_ptr m_current_log_buffer;
5698+};
5699diff --git a/test/helpers/test_fixture.cc b/test/helpers/test_fixture.cc
5700new file mode 100644
5701index 00000000..4d8d7214
5702--- /dev/null
5703+++ b/test/helpers/test_fixture.cc
5704@@ -0,0 +1,18 @@
5705+#include "config.h"
5706+
5707+#include "test_fixture.h"
5708+
5709+#include "torrent/utils/log.h"
5710+
5711+void
5712+test_fixture::setUp() {
5713+ mock_init();
5714+
5715+ log_add_group_output(torrent::LOG_CONNECTION_BIND, "test_output");
5716+ log_add_group_output(torrent::LOG_CONNECTION_FD, "test_output");
5717+}
5718+
5719+void
5720+test_fixture::tearDown() {
5721+ mock_cleanup();
5722+}
5723diff --git a/test/helpers/test_fixture.h b/test/helpers/test_fixture.h
5724new file mode 100644
5725index 00000000..312d5009
5726--- /dev/null
5727+++ b/test/helpers/test_fixture.h
5728@@ -0,0 +1,14 @@
5729+#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H
5730+#define LIBTORRENT_HELPER_TEST_FIXTURE_H
5731+
5732+#include <cppunit/extensions/HelperMacros.h>
5733+
5734+#include "helpers/mock_function.h"
5735+
5736+class test_fixture : public CppUnit::TestFixture {
5737+public:
5738+ void setUp();
5739+ void tearDown();
5740+};
5741+
5742+#endif
5743diff --git a/test/helpers/utils.h b/test/helpers/utils.h
5744new file mode 100644
5745index 00000000..d18450c1
5746--- /dev/null
5747+++ b/test/helpers/utils.h
5748@@ -0,0 +1,60 @@
5749+#ifndef LIBTORRENT_HELPER_UTILS_H
5750+#define LIBTORRENT_HELPER_UTILS_H
5751+
5752+#include <algorithm>
5753+#include <iostream>
5754+#include <cppunit/extensions/TestFactoryRegistry.h>
5755+#include <torrent/utils/log.h>
5756+
5757+static void
5758+dump_failure_log(const failure_type& failure) {
5759+ if (failure.log->empty())
5760+ return;
5761+
5762+ std::cout << std::endl << failure.name << std::endl;
5763+
5764+ // Doesn't print dump messages as log_buffer drops them.
5765+ std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) {
5766+ std::cout << entry.timestamp << ' ' << entry.message << '\n';
5767+ });
5768+
5769+ std::cout << std::flush;
5770+}
5771+
5772+static void
5773+dump_failures(const failure_list_type& failures) {
5774+ if (failures.empty())
5775+ return;
5776+
5777+ std::cout << std::endl
5778+ << "=================" << std::endl
5779+ << "Failed Test Logs:" << std::endl
5780+ << "=================" << std::endl;
5781+
5782+ std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) {
5783+ dump_failure_log(failure);
5784+ });
5785+ std::cout << std::endl;
5786+}
5787+
5788+static
5789+void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) {
5790+ if (c_test_names == NULL || std::string(c_test_names).empty()) {
5791+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
5792+ return;
5793+ }
5794+
5795+ const std::string& test_names(c_test_names);
5796+
5797+ size_t pos = 0;
5798+ size_t next = 0;
5799+
5800+ while ((next = test_names.find(',', pos)) < test_names.size()) {
5801+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest());
5802+ pos = next + 1;
5803+ }
5804+
5805+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest());
5806+}
5807+
5808+#endif
5809diff --git a/test/main.cc b/test/main.cc
5810index e69d3d70..da93fead 100644
5811--- a/test/main.cc
5812+++ b/test/main.cc
5813@@ -1,44 +1,92 @@
5814+#include "config.h"
5815+
5816+#include <cstdlib>
5817 #include <stdexcept>
5818+#include <signal.h>
5819+#include <string.h>
5820 #include <cppunit/BriefTestProgressListener.h>
5821 #include <cppunit/CompilerOutputter.h>
5822 #include <cppunit/TestResult.h>
5823 #include <cppunit/TestResultCollector.h>
5824+#include <cppunit/extensions/HelperMacros.h>
5825 #include <cppunit/extensions/TestFactoryRegistry.h>
5826 #include <cppunit/ui/text/TestRunner.h>
5827
5828-int main(int argc, char* argv[])
5829-{
5830+#ifdef USE_EXECINFO
5831+#include <execinfo.h>
5832+#endif
5833+
5834+#include "helpers/progress_listener.h"
5835+#include "helpers/utils.h"
5836+
5837+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net");
5838+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/net");
5839+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/utils");
5840+
5841+void
5842+do_test_panic(int signum) {
5843+ signal(signum, SIG_DFL);
5844+
5845+ std::cout << std::endl << std::endl << "Caught " << strsignal(signum) << ", dumping stack:" << std::endl << std::endl;
5846+
5847+#ifdef USE_EXECINFO
5848+ void* stackPtrs[20];
5849+
5850+ // Print the stack and exit.
5851+ int stackSize = backtrace(stackPtrs, 20);
5852+ char** stackStrings = backtrace_symbols(stackPtrs, stackSize);
5853+
5854+ for (int i = 0; i < stackSize; ++i)
5855+ std::cout << stackStrings[i] << std::endl;
5856+
5857+#else
5858+ std::cout << "Stack dump not enabled." << std::endl;
5859+#endif
5860+
5861+ std::cout << std::endl;
5862+ torrent::log_cleanup();
5863+ std::abort();
5864+}
5865+
5866+void
5867+register_signal_handlers() {
5868+ struct sigaction sa;
5869+ sigemptyset(&sa.sa_mask);
5870+ sa.sa_flags = SA_RESTART;
5871+ sa.sa_handler = &do_test_panic;
5872+
5873+ if (sigaction(SIGSEGV, &sa, NULL) == -1) {
5874+ std::cout << "Could not register signal handlers." << std::endl;
5875+ exit(-1);
5876+ }
5877+}
5878+
5879+int main(int argc, char* argv[]) {
5880+ register_signal_handlers();
5881+
5882 CppUnit::TestResult controller;
5883 CppUnit::TestResultCollector result;
5884- CppUnit::BriefTestProgressListener progressListener;
5885+ progress_listener progress;
5886
5887 controller.addListener( &result );
5888- controller.addListener( &progressListener );
5889-
5890- // Get the top level suite from the registry
5891- CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
5892+ controller.addListener( &progress );
5893
5894- // Adds the test to the list of test to run
5895 CppUnit::TextUi::TestRunner runner;
5896- runner.addTest( suite );
5897+ add_tests(runner, std::getenv("TEST_NAME"));
5898
5899- // Change the default outputter to a compiler error format outputter
5900- runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
5901- std::cerr ) );
5902 try {
5903 std::cout << "Running ";
5904 runner.run( controller );
5905
5906- std::cerr << std::endl;
5907-
5908+ // TODO: Make outputter.
5909+ dump_failures(progress.failures());
5910+
5911 // Print test in a compiler compatible format.
5912 CppUnit::CompilerOutputter outputter( &result, std::cerr );
5913 outputter.write();
5914
5915 } catch ( std::invalid_argument &e ) { // Test path not resolved
5916- std::cerr << std::endl
5917- << "ERROR: " << e.what()
5918- << std::endl;
5919+ std::cerr << std::endl << "ERROR: " << e.what() << std::endl;
5920 return 1;
5921 }
5922
5923diff --git a/test/net/test_socket_listen.cc b/test/net/test_socket_listen.cc
5924new file mode 100644
5925index 00000000..e86a078b
5926--- /dev/null
5927+++ b/test/net/test_socket_listen.cc
5928@@ -0,0 +1,398 @@
5929+#include "config.h"
5930+
5931+#include "test_socket_listen.h"
5932+
5933+#include "helpers/expect_fd.h"
5934+#include "helpers/expect_utils.h"
5935+#include "helpers/mock_function.h"
5936+#include "helpers/network.h"
5937+
5938+#include <net/socket_listen.h>
5939+#include <torrent/exceptions.h>
5940+#include <torrent/utils/log.h>
5941+
5942+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_socket_listen, "net");
5943+
5944+struct test_sl_deleter {
5945+ void operator()(torrent::socket_listen* sl) const { if (!sl->is_open()) delete sl; }
5946+};
5947+
5948+typedef std::unique_ptr<torrent::socket_listen, test_sl_deleter> test_sl_unique_ptr;
5949+
5950+#define TEST_SL_BEGIN(name) \
5951+ test_sl_unique_ptr sl(new torrent::socket_listen); \
5952+ std::vector<torrent::sa_unique_ptr> sap_cache; \
5953+ lt_log_print(torrent::LOG_MOCK_CALLS, "sl_begin: %s", name); \
5954+ TEST_DEFAULT_SA;
5955+
5956+#define TEST_SL_ASSERT_OPEN(_sap_bind, _sap_result, _flags) \
5957+ TEST_SL_ASSERT_OPEN_PORT(_sap_bind, _sap_result, 5000, 5009, 5005, _flags); \
5958+ CPPUNIT_ASSERT(sl->socket_address_port() == 5005);
5959+
5960+#define TEST_SL_ASSERT_OPEN_PORT(_sap_bind, _sap_result, _first_port, _last_port, _itr_port, _flags) \
5961+ expect_event_open_re(0); \
5962+ CPPUNIT_ASSERT(sl->open(_sap_bind, _first_port, _last_port, _itr_port, _flags)); \
5963+ CPPUNIT_ASSERT(sl->is_open()); \
5964+ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get()));
5965+
5966+#define TEST_SL_ASSERT_OPEN_SEQUENTIAL(_sap_bind, _sap_result, _first_port, _last_port, _flags) \
5967+ expect_event_open_re(0); \
5968+ CPPUNIT_ASSERT(sl->open_sequential(_sap_bind, _first_port, _last_port, _flags)); \
5969+ CPPUNIT_ASSERT(sl->is_open()); \
5970+ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get()));
5971+
5972+#define TEST_SL_ASSERT_OPEN_RANDOMIZE(_sap_bind, _sap_result, _first_port, _last_port, _flags) \
5973+ expect_event_open_re(0); \
5974+ CPPUNIT_ASSERT(sl->open_randomize(_sap_bind, _first_port, _last_port, _flags)); \
5975+ CPPUNIT_ASSERT(sl->is_open()); \
5976+ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get()));
5977+
5978+#define TEST_SL_ASSERT_CLOSED() \
5979+ CPPUNIT_ASSERT(!sl->is_open()); \
5980+ CPPUNIT_ASSERT(sl->file_descriptor() == -1); \
5981+ CPPUNIT_ASSERT(sl->socket_address() == nullptr); \
5982+ CPPUNIT_ASSERT(sl->socket_address_port() == 0);
5983+
5984+#define TEST_SL_CLOSE(_fd) \
5985+ mock_expect(&torrent::fd__close, 0, _fd); \
5986+ mock_expect(&torrent::poll_event_closed, (torrent::Event*)sl.get()); \
5987+ CPPUNIT_ASSERT_NO_THROW(sl->close()); \
5988+ TEST_SL_ASSERT_CLOSED();
5989+
5990+#define TEST_SL_MOCK_CLOSED_PORT_RANGE(_src_sap, _first_port, _last_port) \
5991+ { uint16_t _port = _first_port; do { \
5992+ sap_cache.push_back(torrent::sap_copy(_src_sap)); \
5993+ torrent::sap_set_port(sap_cache.back(), _port); \
5994+ mock_expect(&torrent::fd__bind, -1, 1000, \
5995+ (const sockaddr*)sap_cache.back().get(), \
5996+ (socklen_t)torrent::sap_length(sap_cache.back())); \
5997+ } while (_port++ != _last_port); \
5998+ }
5999+
6000+void
6001+test_socket_listen::test_basic() {
6002+ TEST_SL_BEGIN("basic");
6003+ TEST_SL_ASSERT_CLOSED();
6004+ CPPUNIT_ASSERT(sl->backlog() == SOMAXCONN);
6005+ CPPUNIT_ASSERT(sl->type_name() == std::string("socket_listen"));
6006+}
6007+
6008+void
6009+test_socket_listen::test_open_error() {
6010+ { TEST_SL_BEGIN("open twice");
6011+ expect_fd_inet6_tcp_nonblock(1000);
6012+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6013+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock);
6014+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flag_stream),
6015+ torrent::internal_error);
6016+ TEST_SL_CLOSE(1000);
6017+ };
6018+ { TEST_SL_BEGIN("sin_any, stream, no v4only");
6019+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_any), 5000, 5009, 5005, torrent::fd_flag_stream),
6020+ torrent::internal_error);
6021+ TEST_SL_ASSERT_CLOSED();
6022+ };
6023+}
6024+
6025+void
6026+test_socket_listen::test_open_sap() {
6027+ { TEST_SL_BEGIN("sin6_any, stream");
6028+ expect_fd_inet6_tcp(1000);
6029+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6030+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream);
6031+ TEST_SL_CLOSE(1000);
6032+ };
6033+ { TEST_SL_BEGIN("sin_any, stream|v4only");
6034+ expect_fd_inet_tcp(1000);
6035+ expect_fd_bind_listen(1000, c_sin_any_5005);
6036+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only);
6037+ TEST_SL_CLOSE(1000);
6038+ };
6039+ { TEST_SL_BEGIN("sin_1, stream|v4only");
6040+ expect_fd_inet_tcp(1000);
6041+ expect_fd_bind_listen(1000, c_sin_1_5005);
6042+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin_1), c_sin_1_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only);
6043+ TEST_SL_CLOSE(1000);
6044+ };
6045+ { TEST_SL_BEGIN("sin6_any, stream|v6only");
6046+ expect_fd_inet6_tcp(1000);
6047+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
6048+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6049+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v6only);
6050+ TEST_SL_CLOSE(1000);
6051+ };
6052+ { TEST_SL_BEGIN("sin6_1, stream|v6only");
6053+ expect_fd_inet6_tcp(1000);
6054+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
6055+ expect_fd_bind_listen(1000, c_sin6_1_5005);
6056+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_1), c_sin6_1_5005, torrent::fd_flag_stream | torrent::fd_flag_v6only);
6057+ TEST_SL_CLOSE(1000);
6058+ };
6059+}
6060+
6061+void
6062+test_socket_listen::test_open_sap_error() {
6063+ { TEST_SL_BEGIN("unspec");
6064+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sa_make_unspec(), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error);
6065+ TEST_SL_ASSERT_CLOSED();
6066+ };
6067+ { TEST_SL_BEGIN("unix");
6068+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sa_make_unix("test"), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error);
6069+ TEST_SL_ASSERT_CLOSED();
6070+ };
6071+ { TEST_SL_BEGIN("sin_any_5005");
6072+ 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);
6073+ TEST_SL_ASSERT_CLOSED();
6074+ };
6075+ { TEST_SL_BEGIN("sin6_any_5005");
6076+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any_5005), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error);
6077+ TEST_SL_ASSERT_CLOSED();
6078+ };
6079+ { TEST_SL_BEGIN("sin_any");
6080+ 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);
6081+ TEST_SL_ASSERT_CLOSED();
6082+ };
6083+ { TEST_SL_BEGIN("sin_1, v4mapped");
6084+ 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);
6085+ TEST_SL_ASSERT_CLOSED();
6086+ };
6087+ { TEST_SL_BEGIN("sin_broadcast");
6088+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_bc), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error);
6089+ TEST_SL_ASSERT_CLOSED();
6090+ };
6091+}
6092+
6093+void
6094+test_socket_listen::test_open_flags() {
6095+ { TEST_SL_BEGIN("sin_any, stream|v4only|nonblock");
6096+ expect_fd_inet_tcp_nonblock(1000);
6097+ expect_fd_bind_listen(1000, c_sin_any_5005);
6098+ 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);
6099+ TEST_SL_CLOSE(1000);
6100+ };
6101+ { TEST_SL_BEGIN("sin6_any, stream|nonblock");
6102+ expect_fd_inet6_tcp_nonblock(1000);
6103+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6104+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock);
6105+ TEST_SL_CLOSE(1000);
6106+ };
6107+ { TEST_SL_BEGIN("sin_any, stream|v4only|reuse_address");
6108+ expect_fd_inet_tcp(1000);
6109+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
6110+ expect_fd_bind_listen(1000, c_sin_any_5005);
6111+ 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);
6112+ TEST_SL_CLOSE(1000);
6113+ };
6114+ { TEST_SL_BEGIN("sin6_any, stream|reuse_address");
6115+ expect_fd_inet6_tcp(1000);
6116+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
6117+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6118+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_reuse_address);
6119+ TEST_SL_CLOSE(1000);
6120+ };
6121+ { TEST_SL_BEGIN("sin_any, stream|v4only|nonblock|reuse_address");
6122+ expect_fd_inet_tcp_nonblock(1000);
6123+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
6124+ expect_fd_bind_listen(1000, c_sin_any_5005);
6125+ 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);
6126+ TEST_SL_CLOSE(1000);
6127+ };
6128+ { TEST_SL_BEGIN("sin6_any, stream|nonblock|reuse_address");
6129+ expect_fd_inet6_tcp_nonblock_reuseaddr(1000);
6130+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6131+ 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);
6132+ TEST_SL_CLOSE(1000);
6133+ };
6134+}
6135+
6136+void
6137+test_socket_listen::test_open_flags_error() {
6138+ { TEST_SL_BEGIN("sin6_any, fd_flags(0)");
6139+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flags(0)), torrent::internal_error);
6140+ TEST_SL_ASSERT_CLOSED();
6141+ };
6142+ { TEST_SL_BEGIN("sin6_any, fd_flags(0xffff)");
6143+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flags(0xffff)), torrent::internal_error);
6144+ TEST_SL_ASSERT_CLOSED();
6145+ };
6146+}
6147+
6148+void
6149+test_socket_listen::test_open_port_single() {
6150+ { TEST_SL_BEGIN("sin6_any, stream");
6151+ expect_fd_inet6_tcp(1000);
6152+ expect_fd_bind_listen(1000, c_sin6_any_5000);
6153+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5000, 5000, torrent::fd_flag_stream);
6154+ TEST_SL_CLOSE(1000);
6155+ };
6156+ { TEST_SL_BEGIN("sin_any, stream");
6157+ expect_fd_inet_tcp(1000);
6158+ expect_fd_bind_listen(1000, c_sin_any_5000);
6159+ 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);
6160+ TEST_SL_CLOSE(1000);
6161+ };
6162+}
6163+
6164+void
6165+test_socket_listen::test_open_port_single_error() {
6166+ { TEST_SL_BEGIN("sin6_any, 0, 0, 0");
6167+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 0, 0, torrent::fd_flag_stream), torrent::internal_error);
6168+ TEST_SL_ASSERT_CLOSED();
6169+ };
6170+ { TEST_SL_BEGIN("sin6_any, 1000, 0, 0");
6171+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 1000, 0, 0, torrent::fd_flag_stream), torrent::internal_error);
6172+ TEST_SL_ASSERT_CLOSED();
6173+ };
6174+ { TEST_SL_BEGIN("sin6_any, 0, 1000, 0");
6175+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 1000, 0, torrent::fd_flag_stream), torrent::internal_error);
6176+ TEST_SL_ASSERT_CLOSED();
6177+ };
6178+ { TEST_SL_BEGIN("sin6_any, 0, 0, 500");
6179+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 0, 500, torrent::fd_flag_stream), torrent::internal_error);
6180+ TEST_SL_ASSERT_CLOSED();
6181+ };
6182+ { TEST_SL_BEGIN("sin6_any, 0, 1000, 500");
6183+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 1000, 500, torrent::fd_flag_stream), torrent::internal_error);
6184+ TEST_SL_ASSERT_CLOSED();
6185+ };
6186+}
6187+
6188+void
6189+test_socket_listen::test_open_port_range() {
6190+ { TEST_SL_BEGIN("sin6_any, stream, first");
6191+ expect_fd_inet6_tcp(1000);
6192+ expect_fd_bind_listen(1000, c_sin6_any_5000);
6193+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, 5000, torrent::fd_flag_stream);
6194+ TEST_SL_CLOSE(1000);
6195+ };
6196+ { TEST_SL_BEGIN("sin6_any, stream, from first to middle port");
6197+ expect_fd_inet6_tcp(1000);
6198+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5004);
6199+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6200+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5000, torrent::fd_flag_stream);
6201+ TEST_SL_CLOSE(1000);
6202+ };
6203+ { TEST_SL_BEGIN("sin6_any, stream, from first to last port");
6204+ expect_fd_inet6_tcp(1000);
6205+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5009);
6206+ expect_fd_bind_listen(1000, c_sin6_any_5010);
6207+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5000, torrent::fd_flag_stream);
6208+ TEST_SL_CLOSE(1000);
6209+ };
6210+ { TEST_SL_BEGIN("sin6_any, stream, middle");
6211+ expect_fd_inet6_tcp(1000);
6212+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6213+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5005, torrent::fd_flag_stream);
6214+ TEST_SL_CLOSE(1000);
6215+ };
6216+ { TEST_SL_BEGIN("sin6_any, stream, from middle to last port");
6217+ expect_fd_inet6_tcp(1000);
6218+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5005, 5009);
6219+ expect_fd_bind_listen(1000, c_sin6_any_5010);
6220+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5005, torrent::fd_flag_stream);
6221+ TEST_SL_CLOSE(1000);
6222+ };
6223+ { TEST_SL_BEGIN("sin6_any, stream, last");
6224+ expect_fd_inet6_tcp(1000);
6225+ expect_fd_bind_listen(1000, c_sin6_any_5010);
6226+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5010, torrent::fd_flag_stream);
6227+ TEST_SL_CLOSE(1000);
6228+ };
6229+ { TEST_SL_BEGIN("sin6_any, stream, from last to first port");
6230+ expect_fd_inet6_tcp(1000);
6231+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5010, 5010);
6232+ expect_fd_bind_listen(1000, c_sin6_any_5000);
6233+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, 5010, torrent::fd_flag_stream);
6234+ TEST_SL_CLOSE(1000);
6235+ };
6236+ { TEST_SL_BEGIN("sin6_any, stream, from last to middle port");
6237+ expect_fd_inet6_tcp(1000);
6238+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5010, 5010);
6239+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5004);
6240+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6241+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5010, torrent::fd_flag_stream);
6242+ TEST_SL_CLOSE(1000);
6243+ };
6244+}
6245+
6246+void
6247+test_socket_listen::test_open_port_range_error() {
6248+ { TEST_SL_BEGIN("sin6_any, first > last");
6249+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 4999, 5000, torrent::fd_flag_stream), torrent::internal_error);
6250+ TEST_SL_ASSERT_CLOSED();
6251+ };
6252+ { TEST_SL_BEGIN("sin6_any, first > itr");
6253+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5001, 5009, 5000, torrent::fd_flag_stream), torrent::internal_error);
6254+ TEST_SL_ASSERT_CLOSED();
6255+ };
6256+ { TEST_SL_BEGIN("sin6_any, itr > last");
6257+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5010, torrent::fd_flag_stream), torrent::internal_error);
6258+ TEST_SL_ASSERT_CLOSED();
6259+ };
6260+ { TEST_SL_BEGIN("sin6_any, min first > last");
6261+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 2, 1, 2, torrent::fd_flag_stream), torrent::internal_error);
6262+ TEST_SL_ASSERT_CLOSED();
6263+ };
6264+ { TEST_SL_BEGIN("sin6_any, min first > itr");
6265+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 2, 1000, 1, torrent::fd_flag_stream), torrent::internal_error);
6266+ TEST_SL_ASSERT_CLOSED();
6267+ };
6268+ { TEST_SL_BEGIN("sin6_any, min itr > last");
6269+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 1, 2, 3, torrent::fd_flag_stream), torrent::internal_error);
6270+ TEST_SL_ASSERT_CLOSED();
6271+ };
6272+ { TEST_SL_BEGIN("sin6_any, max first > last");
6273+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xffff, 0xfffe, 0xffff, torrent::fd_flag_stream), torrent::internal_error);
6274+ TEST_SL_ASSERT_CLOSED();
6275+ };
6276+ { TEST_SL_BEGIN("sin6_any, max first > itr");
6277+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xffff, 0xffff, 0xfffe, torrent::fd_flag_stream), torrent::internal_error);
6278+ TEST_SL_ASSERT_CLOSED();
6279+ };
6280+ { TEST_SL_BEGIN("sin6_any, max itr > last");
6281+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xfffe, 0xfffe, 0xffff, torrent::fd_flag_stream), torrent::internal_error);
6282+ TEST_SL_ASSERT_CLOSED();
6283+ };
6284+}
6285+
6286+void
6287+test_socket_listen::test_open_sequential() {
6288+ { TEST_SL_BEGIN("sin6_any, stream");
6289+ expect_fd_inet6_tcp(1000);
6290+ expect_fd_bind_listen(1000, c_sin6_any_5000);
6291+ TEST_SL_ASSERT_OPEN_SEQUENTIAL(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, torrent::fd_flag_stream);
6292+ TEST_SL_CLOSE(1000);
6293+ };
6294+}
6295+
6296+void
6297+test_socket_listen::test_open_randomize() {
6298+ { TEST_SL_BEGIN("sin6_any, stream");
6299+ expect_random_uniform_uint16(5005, 5000, 5010);
6300+ expect_fd_inet6_tcp(1000);
6301+ expect_fd_bind_listen(1000, c_sin6_any_5005);
6302+ TEST_SL_ASSERT_OPEN_RANDOMIZE(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, torrent::fd_flag_stream);
6303+ TEST_SL_CLOSE(1000);
6304+ };
6305+}
6306+
6307+// deal with reuse error
6308+
6309+void
6310+test_socket_listen::test_accept() {
6311+ { TEST_SL_BEGIN("sin6_any, stream");
6312+ expect_fd_inet6_tcp(1000);
6313+ expect_fd_bind_listen(1000, c_sin6_any_5000);
6314+ TEST_SL_ASSERT_OPEN_SEQUENTIAL(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, torrent::fd_flag_stream);
6315+
6316+ std::vector<torrent::fd_sap_tuple> accepted_connections;
6317+
6318+ sl->set_slot_accepted([&accepted_connections](int accept_fd, torrent::sa_unique_ptr sap) {
6319+ accepted_connections.push_back(torrent::fd_sap_tuple{accept_fd, std::move(sap)});
6320+ });
6321+
6322+ // CPPUNIT_ASSERT(accepted_connections.size() > 0 && torrent::fd_sap_equal(accepted_connections[0], torrent::fd_sap_tuple{2000, torrent::sap_copy(sin6_1_5100)}));
6323+
6324+ TEST_SL_CLOSE(1000);
6325+ };
6326+}
6327diff --git a/test/net/test_socket_listen.h b/test/net/test_socket_listen.h
6328new file mode 100644
6329index 00000000..5d06f7f3
6330--- /dev/null
6331+++ b/test/net/test_socket_listen.h
6332@@ -0,0 +1,44 @@
6333+#include "helpers/test_fixture.h"
6334+
6335+class test_socket_listen : public test_fixture {
6336+ CPPUNIT_TEST_SUITE(test_socket_listen);
6337+
6338+ CPPUNIT_TEST(test_basic);
6339+
6340+ CPPUNIT_TEST(test_open_error);
6341+ CPPUNIT_TEST(test_open_sap);
6342+ CPPUNIT_TEST(test_open_sap_error);
6343+ CPPUNIT_TEST(test_open_flags);
6344+ CPPUNIT_TEST(test_open_flags_error);
6345+
6346+ CPPUNIT_TEST(test_open_port_single);
6347+ CPPUNIT_TEST(test_open_port_single_error);
6348+ CPPUNIT_TEST(test_open_port_range);
6349+ CPPUNIT_TEST(test_open_port_range_error);
6350+
6351+ CPPUNIT_TEST(test_open_sequential);
6352+ CPPUNIT_TEST(test_open_randomize);
6353+
6354+ CPPUNIT_TEST(test_accept);
6355+
6356+ CPPUNIT_TEST_SUITE_END();
6357+
6358+public:
6359+ void test_basic();
6360+
6361+ void test_open_error();
6362+ void test_open_sap();
6363+ void test_open_sap_error();
6364+ void test_open_flags();
6365+ void test_open_flags_error();
6366+
6367+ void test_open_port_single();
6368+ void test_open_port_single_error();
6369+ void test_open_port_range();
6370+ void test_open_port_range_error();
6371+
6372+ void test_open_sequential();
6373+ void test_open_randomize();
6374+
6375+ void test_accept();
6376+};
6377diff --git a/test/torrent/net/test_address_info.cc b/test/torrent/net/test_address_info.cc
6378new file mode 100644
6379index 00000000..e3ee24d1
6380--- /dev/null
6381+++ b/test/torrent/net/test_address_info.cc
6382@@ -0,0 +1,62 @@
6383+#include "config.h"
6384+
6385+#include "test_address_info.h"
6386+
6387+#include "helpers/network.h"
6388+#include "torrent/net/address_info.h"
6389+#include "torrent/net/socket_address.h"
6390+
6391+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_address_info, "torrent/net");
6392+
6393+void
6394+test_address_info::test_basic() {
6395+ 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)));
6396+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6|aif_any>(std::bind(torrent::ai_get_addrinfo, "::", nullptr, nullptr, std::placeholders::_1)));
6397+
6398+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet> (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", nullptr, nullptr, std::placeholders::_1)));
6399+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6>(std::bind(torrent::ai_get_addrinfo, "ff01::1", nullptr, nullptr, std::placeholders::_1)));
6400+ 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)));
6401+
6402+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet> (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", "22123", nullptr, std::placeholders::_1), 22123));
6403+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6>(std::bind(torrent::ai_get_addrinfo, "2001:db8:a::", "22123", nullptr, std::placeholders::_1), 22123));
6404+
6405+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_none> (std::bind(torrent::ai_get_addrinfo, "localhost", nullptr, nullptr, std::placeholders::_1)));
6406+
6407+ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "1.1.1.300", nullptr, nullptr, std::placeholders::_1), EAI_NONAME));
6408+ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "2001:db8:a::22123", nullptr, nullptr, std::placeholders::_1), EAI_NONAME));
6409+}
6410+
6411+void
6412+test_address_info::test_numericserv() {
6413+ 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)));
6414+
6415+ 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));
6416+}
6417+
6418+void
6419+test_address_info::test_helpers() {
6420+ torrent::sin_unique_ptr sin_zero = torrent::sin_from_sa(wrap_ai_get_first_sa("0.0.0.0"));
6421+ CPPUNIT_ASSERT(sin_zero != nullptr);
6422+ CPPUNIT_ASSERT(sin_zero->sin_family == AF_INET);
6423+ CPPUNIT_ASSERT(sin_zero->sin_port == 0);
6424+ CPPUNIT_ASSERT(sin_zero->sin_addr.s_addr == in_addr().s_addr);
6425+
6426+ torrent::sin_unique_ptr sin_1 = torrent::sin_from_sa(wrap_ai_get_first_sa("1.2.3.4"));
6427+ CPPUNIT_ASSERT(sin_1 != nullptr);
6428+ CPPUNIT_ASSERT(sin_1->sin_family == AF_INET);
6429+ CPPUNIT_ASSERT(sin_1->sin_port == 0);
6430+ CPPUNIT_ASSERT(sin_1->sin_addr.s_addr == htonl(0x01020304));
6431+
6432+ torrent::sin6_unique_ptr sin6_zero = torrent::sin6_from_sa(wrap_ai_get_first_sa("::"));
6433+ CPPUNIT_ASSERT(sin6_zero != nullptr);
6434+ CPPUNIT_ASSERT(sin6_zero->sin6_family == AF_INET6);
6435+ CPPUNIT_ASSERT(sin6_zero->sin6_port == 0);
6436+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_zero->sin6_addr, in6_addr{0}));
6437+
6438+ torrent::sin6_unique_ptr sin6_1 = torrent::sin6_from_sa(wrap_ai_get_first_sa("ff01::1"));
6439+ CPPUNIT_ASSERT(sin6_1 != nullptr);
6440+ CPPUNIT_ASSERT(sin6_1->sin6_family == AF_INET6);
6441+ CPPUNIT_ASSERT(sin6_1->sin6_port == 0);
6442+ 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}));
6443+ 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}));
6444+}
6445diff --git a/test/torrent/net/test_address_info.h b/test/torrent/net/test_address_info.h
6446new file mode 100644
6447index 00000000..c2ce9188
6448--- /dev/null
6449+++ b/test/torrent/net/test_address_info.h
6450@@ -0,0 +1,19 @@
6451+#include <cppunit/extensions/HelperMacros.h>
6452+
6453+class test_address_info : public CppUnit::TestFixture {
6454+ CPPUNIT_TEST_SUITE(test_address_info);
6455+
6456+ CPPUNIT_TEST(test_basic);
6457+ CPPUNIT_TEST(test_numericserv);
6458+ CPPUNIT_TEST(test_helpers);
6459+
6460+ CPPUNIT_TEST_SUITE_END();
6461+
6462+public:
6463+ void setUp() {}
6464+ void tearDown() {}
6465+
6466+ void test_basic();
6467+ void test_numericserv();
6468+ void test_helpers();
6469+};
6470diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc
6471new file mode 100644
6472index 00000000..3cab0c5e
6473--- /dev/null
6474+++ b/test/torrent/net/test_fd.cc
6475@@ -0,0 +1,24 @@
6476+#include "config.h"
6477+
6478+#include "test_fd.h"
6479+
6480+#include <torrent/net/fd.h>
6481+
6482+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
6483+
6484+void
6485+test_fd::test_valid_flags() {
6486+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
6487+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
6488+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
6489+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
6490+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
6491+
6492+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
6493+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
6494+
6495+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
6496+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
6497+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all)));
6498+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132)));
6499+}
6500diff --git a/test/torrent/net/test_fd.h b/test/torrent/net/test_fd.h
6501new file mode 100644
6502index 00000000..6ba718fc
6503--- /dev/null
6504+++ b/test/torrent/net/test_fd.h
6505@@ -0,0 +1,12 @@
6506+#include "helpers/test_fixture.h"
6507+
6508+class test_fd : public test_fixture {
6509+ CPPUNIT_TEST_SUITE(test_fd);
6510+
6511+ CPPUNIT_TEST(test_valid_flags);
6512+
6513+ CPPUNIT_TEST_SUITE_END();
6514+
6515+public:
6516+ void test_valid_flags();
6517+};
6518diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc
6519new file mode 100644
6520index 00000000..8a1b0c8a
6521--- /dev/null
6522+++ b/test/torrent/net/test_socket_address.cc
6523@@ -0,0 +1,383 @@
6524+#include "config.h"
6525+
6526+#include "test_socket_address.h"
6527+
6528+#include "helpers/network.h"
6529+#include "torrent/exceptions.h"
6530+#include "torrent/net/socket_address.h"
6531+
6532+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_socket_address, "torrent/net");
6533+
6534+void
6535+test_socket_address::test_sa_is_any() {
6536+ TEST_DEFAULT_SA;
6537+
6538+ CPPUNIT_ASSERT(torrent::sap_is_any(sin_any));
6539+ CPPUNIT_ASSERT(torrent::sap_is_any(sin_any_5000));
6540+ CPPUNIT_ASSERT(torrent::sap_is_any(sin6_v4_any));
6541+ CPPUNIT_ASSERT(torrent::sap_is_any(sin6_v4_any_5000));
6542+
6543+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_bc));
6544+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_1));
6545+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin6_1));
6546+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_bc_5000));
6547+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_1_5000));
6548+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin6_1_5000));
6549+
6550+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_bc));
6551+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_1));
6552+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin6_1));
6553+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_bc_5000));
6554+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_1_5000));
6555+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin6_1_5000));
6556+}
6557+
6558+void
6559+test_socket_address::test_sa_is_broadcast() {
6560+ TEST_DEFAULT_SA;
6561+
6562+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin_bc));
6563+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin_bc_5000));
6564+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin6_v4_bc));
6565+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin6_v4_bc_5000));
6566+
6567+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_any));
6568+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_1));
6569+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_any));
6570+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_1));
6571+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_any_5000));
6572+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_1_5000));
6573+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_any_5000));
6574+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_1_5000));
6575+
6576+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_any));
6577+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_1));
6578+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_any));
6579+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_1));
6580+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_any_5000));
6581+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_1_5000));
6582+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_any_5000));
6583+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_1_5000));
6584+}
6585+
6586+void
6587+test_socket_address::test_make() {
6588+ torrent::sa_unique_ptr sa_unspec = torrent::sa_make_unspec();
6589+ CPPUNIT_ASSERT(sa_unspec != nullptr);
6590+ CPPUNIT_ASSERT(sa_unspec->sa_family == AF_UNSPEC);
6591+
6592+ torrent::sa_unique_ptr sa_inet = torrent::sa_make_inet();
6593+ CPPUNIT_ASSERT(sa_inet != nullptr);
6594+ CPPUNIT_ASSERT(sa_inet->sa_family == AF_INET);
6595+
6596+ sockaddr_in* sin_inet = reinterpret_cast<sockaddr_in*>(sa_inet.get());
6597+ CPPUNIT_ASSERT(sin_inet->sin_family == AF_INET);
6598+ CPPUNIT_ASSERT(sin_inet->sin_port == 0);
6599+ CPPUNIT_ASSERT(sin_inet->sin_addr.s_addr == in_addr().s_addr);
6600+
6601+ torrent::sa_unique_ptr sa_inet6 = torrent::sa_make_inet6();
6602+ CPPUNIT_ASSERT(sa_inet6 != nullptr);
6603+ CPPUNIT_ASSERT(sa_inet6->sa_family == AF_INET6);
6604+
6605+ sockaddr_in6* sin6_inet6 = reinterpret_cast<sockaddr_in6*>(sa_inet6.get());
6606+ CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6);
6607+ CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0);
6608+ CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0);
6609+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0}));
6610+ CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0);
6611+
6612+ torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix("");
6613+ CPPUNIT_ASSERT(sa_unix != nullptr);
6614+ CPPUNIT_ASSERT(sa_unix->sa_family == AF_UNIX);
6615+}
6616+
6617+void
6618+test_socket_address::test_sin_from_sa() {
6619+ torrent::sa_unique_ptr sa_zero = wrap_ai_get_first_sa("0.0.0.0");
6620+ torrent::sin_unique_ptr sin_zero;
6621+
6622+ CPPUNIT_ASSERT(sa_zero != nullptr);
6623+ CPPUNIT_ASSERT_NO_THROW({ sin_zero = torrent::sin_from_sa(std::move(sa_zero)); });
6624+ CPPUNIT_ASSERT(sa_zero == nullptr);
6625+ CPPUNIT_ASSERT(sin_zero != nullptr);
6626+
6627+ CPPUNIT_ASSERT(sin_zero->sin_addr.s_addr == htonl(0x0));
6628+
6629+ torrent::sa_unique_ptr sa_inet = wrap_ai_get_first_sa("1.2.3.4");
6630+ torrent::sin_unique_ptr sin_inet;
6631+
6632+ CPPUNIT_ASSERT(sa_inet != nullptr);
6633+ CPPUNIT_ASSERT_NO_THROW({ sin_inet = torrent::sin_from_sa(std::move(sa_inet)); });
6634+ CPPUNIT_ASSERT(sa_inet == nullptr);
6635+ CPPUNIT_ASSERT(sin_inet != nullptr);
6636+
6637+ CPPUNIT_ASSERT(sin_inet->sin_addr.s_addr == htonl(0x01020304));
6638+
6639+ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_unique_ptr()), torrent::internal_error);
6640+ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_make_unspec()), torrent::internal_error);
6641+ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_make_inet6()), torrent::internal_error);
6642+}
6643+
6644+void
6645+test_socket_address::test_sin6_from_sa() {
6646+ torrent::sa_unique_ptr sa_zero = wrap_ai_get_first_sa("::");
6647+ torrent::sin6_unique_ptr sin6_zero;
6648+
6649+ CPPUNIT_ASSERT(sa_zero != nullptr);
6650+ CPPUNIT_ASSERT_NO_THROW({ sin6_zero = torrent::sin6_from_sa(std::move(sa_zero)); });
6651+ CPPUNIT_ASSERT(sa_zero == nullptr);
6652+ CPPUNIT_ASSERT(sin6_zero != nullptr);
6653+
6654+ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[0] == 0x0);
6655+ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[1] == 0x0);
6656+ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[15] == 0x0);
6657+
6658+ torrent::sa_unique_ptr sa_inet6 = wrap_ai_get_first_sa("ff01::1");
6659+ torrent::sin6_unique_ptr sin6_inet6;
6660+
6661+ CPPUNIT_ASSERT(sa_inet6 != nullptr);
6662+ CPPUNIT_ASSERT_NO_THROW({ sin6_inet6 = torrent::sin6_from_sa(std::move(sa_inet6)); });
6663+ CPPUNIT_ASSERT(sa_inet6 == nullptr);
6664+ CPPUNIT_ASSERT(sin6_inet6 != nullptr);
6665+
6666+ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[0] == 0xff);
6667+ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[1] == 0x01);
6668+ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[15] == 0x01);
6669+
6670+ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_unique_ptr()), torrent::internal_error);
6671+ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_make_unspec()), torrent::internal_error);
6672+ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_make_inet()), torrent::internal_error);
6673+}
6674+
6675+void
6676+test_socket_address::test_sa_equal() {
6677+ TEST_DEFAULT_SA;
6678+
6679+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_unspec()));
6680+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_inet(), torrent::sa_make_inet()));
6681+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_inet6(), torrent::sa_make_inet6()));
6682+
6683+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_inet()));
6684+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_inet6()));
6685+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_inet(), torrent::sa_make_inet6()));
6686+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_inet6(), torrent::sa_make_inet()));
6687+
6688+ CPPUNIT_ASSERT(torrent::sap_equal(sin_1, sin_1));
6689+ CPPUNIT_ASSERT(torrent::sap_equal(sin_1, c_sin_1));
6690+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin_1, sin_1));
6691+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin_1, c_sin_1));
6692+
6693+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1, sin_2));
6694+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1, c_sin_2));
6695+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin_1, sin_2));
6696+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin_1, c_sin_2));
6697+
6698+ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1, sin6_1));
6699+ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1, c_sin6_1));
6700+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin6_1, sin6_1));
6701+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin6_1, c_sin6_1));
6702+
6703+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1, sin6_2));
6704+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1, c_sin6_2));
6705+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin6_1, sin6_2));
6706+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin6_1, c_sin6_2));
6707+
6708+ CPPUNIT_ASSERT(torrent::sap_equal(sin_1_5000, sin_1_5000));
6709+ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1_5000, sin6_1_5000));
6710+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_1_5100));
6711+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_1_5100));
6712+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_2_5000));
6713+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_2_5000));
6714+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_2_5100));
6715+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_2_5100));
6716+
6717+ CPPUNIT_ASSERT_THROW(torrent::sap_equal(torrent::sa_make_unix(""), torrent::sa_make_unix("")), torrent::internal_error);
6718+ CPPUNIT_ASSERT_THROW(torrent::sap_equal(torrent::sa_make_unix(""), sin6_1), torrent::internal_error);
6719+ CPPUNIT_ASSERT_THROW(torrent::sap_equal(sin6_1, torrent::sa_make_unix("")), torrent::internal_error);
6720+}
6721+
6722+void
6723+test_socket_address::test_sa_equal_addr() {
6724+ TEST_DEFAULT_SA;
6725+
6726+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_unspec()));
6727+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_inet(), torrent::sa_make_inet()));
6728+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_inet6(), torrent::sa_make_inet6()));
6729+
6730+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_inet()));
6731+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_inet6()));
6732+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_inet(), torrent::sa_make_inet6()));
6733+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_inet6(), torrent::sa_make_inet()));
6734+
6735+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1, sin_1));
6736+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1, c_sin_1));
6737+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin_1, sin_1));
6738+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin_1, c_sin_1));
6739+
6740+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1, sin_2));
6741+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1, c_sin_2));
6742+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin_1, sin_2));
6743+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin_1, c_sin_2));
6744+
6745+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1, sin6_1));
6746+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1, c_sin6_1));
6747+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin6_1, sin6_1));
6748+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin6_1, c_sin6_1));
6749+
6750+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1, sin6_2));
6751+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1, c_sin6_2));
6752+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin6_1, sin6_2));
6753+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin6_1, c_sin6_2));
6754+
6755+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1_5000, sin_1_5000));
6756+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1_5000, sin6_1_5000));
6757+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1_5000, sin_1_5100));
6758+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1_5000, sin6_1_5100));
6759+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1_5000, sin_2_5000));
6760+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1_5000, sin6_2_5000));
6761+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1_5000, sin_2_5100));
6762+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1_5000, sin6_2_5100));
6763+
6764+ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(torrent::sa_make_unix(""), torrent::sa_make_unix("")), torrent::internal_error);
6765+ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(torrent::sa_make_unix(""), sin6_1), torrent::internal_error);
6766+ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(sin6_1, torrent::sa_make_unix("")), torrent::internal_error);
6767+}
6768+
6769+void
6770+test_socket_address::test_sa_copy() {
6771+ TEST_DEFAULT_SA;
6772+
6773+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_unspec()), torrent::sa_make_unspec()));
6774+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_inet()), sin_any));
6775+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_inet6()), sin6_any));
6776+
6777+ CPPUNIT_ASSERT(torrent::sap_copy(sin_1).get() != sin_1.get());
6778+ CPPUNIT_ASSERT(torrent::sap_copy(c_sin_1).get() != c_sin_1.get());
6779+ CPPUNIT_ASSERT(torrent::sap_copy(sin6_1).get() != sin6_1.get());
6780+ CPPUNIT_ASSERT(torrent::sap_copy(c_sin6_1).get() != c_sin6_1.get());
6781+ CPPUNIT_ASSERT(torrent::sap_copy(sin_1_5000).get() != sin_1_5000.get());
6782+ CPPUNIT_ASSERT(torrent::sap_copy(sin6_1_5000).get() != sin6_1_5000.get());
6783+
6784+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1), sin_1));
6785+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1), c_sin_1));
6786+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin_1), sin_1));
6787+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin_1), c_sin_1));
6788+
6789+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1), sin6_1));
6790+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1), c_sin6_1));
6791+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin6_1), sin6_1));
6792+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin6_1), c_sin6_1));
6793+
6794+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1_5000), sin_1_5000));
6795+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1_5000), sin6_1_5000));
6796+
6797+ auto sin6_flags = torrent::sap_copy(sin6_1_5000);
6798+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_flowinfo = 0x12345678;
6799+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_scope_id = 0x12345678;
6800+
6801+ // TODO: Need 'strict' equal test.
6802+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_flags), sin6_flags));
6803+
6804+ CPPUNIT_ASSERT_THROW(torrent::sap_copy(torrent::sa_unique_ptr()), torrent::internal_error);
6805+ CPPUNIT_ASSERT_THROW(torrent::sap_copy(torrent::c_sa_unique_ptr()), torrent::internal_error);
6806+}
6807+
6808+void
6809+test_socket_address::test_sa_copy_addr() {
6810+ TEST_DEFAULT_SA;
6811+
6812+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_unspec()), torrent::sa_make_unspec()));
6813+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet()), sin_any));
6814+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet6()), sin6_any));
6815+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_unspec(), 5000), torrent::sa_make_unspec()));
6816+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet(), 5000), sin_any_5000));
6817+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet6(), 5000), sin6_any_5000));
6818+
6819+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin_1).get() != sin_1.get());
6820+ CPPUNIT_ASSERT(torrent::sap_copy_addr(c_sin_1).get() != c_sin_1.get());
6821+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin6_1).get() != sin6_1.get());
6822+ CPPUNIT_ASSERT(torrent::sap_copy_addr(c_sin6_1).get() != c_sin6_1.get());
6823+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin_1_5000).get() != sin_1_5000.get());
6824+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin6_1_5000).get() != sin6_1_5000.get());
6825+
6826+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1), sin_1));
6827+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1), c_sin_1));
6828+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1), sin_1));
6829+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1), c_sin_1));
6830+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1, 5000), sin_1_5000));
6831+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1, 5000), c_sin_1_5000));
6832+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1, 5000), sin_1_5000));
6833+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1, 5000), c_sin_1_5000));
6834+
6835+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1), sin6_1));
6836+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1), c_sin6_1));
6837+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1), sin6_1));
6838+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1), c_sin6_1));
6839+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1, 5000), sin6_1_5000));
6840+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1, 5000), c_sin6_1_5000));
6841+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1, 5000), sin6_1_5000));
6842+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1, 5000), c_sin6_1_5000));
6843+
6844+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1_5000), sin_1));
6845+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1_5000), sin6_1));
6846+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1_5000, 5100), sin_1_5100));
6847+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1_5000, 5100), sin6_1_5100));
6848+
6849+ auto sin6_flags = wrap_ai_get_first_sa("ff01::1", "5555");
6850+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_flowinfo = 0x12345678;
6851+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_scope_id = 0x12345678;
6852+
6853+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_flags), sin6_1));
6854+
6855+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::sa_unique_ptr()), torrent::internal_error);
6856+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::c_sa_unique_ptr()), torrent::internal_error);
6857+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::sa_unique_ptr(), 5000), torrent::internal_error);
6858+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::c_sa_unique_ptr(), 5000), torrent::internal_error);
6859+}
6860+
6861+void
6862+test_socket_address::test_sa_from_v4mapped() {
6863+ TEST_DEFAULT_SA;
6864+
6865+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_any), sin_any));
6866+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_any)));
6867+
6868+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_1), sin_1));
6869+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_1)));
6870+
6871+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_bc), sin_bc));
6872+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_bc)));
6873+
6874+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_unspec()), torrent::internal_error);
6875+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_inet()), torrent::internal_error);
6876+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_unix("")), torrent::internal_error);
6877+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_any), torrent::internal_error);
6878+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_bc), torrent::internal_error);
6879+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_1), torrent::internal_error);
6880+}
6881+
6882+void
6883+test_socket_address::test_sa_to_v4mapped() {
6884+ TEST_DEFAULT_SA;
6885+
6886+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_any), sin6_v4_any));
6887+ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_any)));
6888+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_any)));
6889+
6890+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_bc), sin6_v4_bc));
6891+ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_bc)));
6892+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_bc)));
6893+
6894+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_1), sin6_v4_1));
6895+ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_1)));
6896+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_1)));
6897+
6898+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_unspec()), torrent::internal_error);
6899+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_inet6()), torrent::internal_error);
6900+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_unix("")), torrent::internal_error);
6901+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_any), torrent::internal_error);
6902+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_1), torrent::internal_error);
6903+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_any), torrent::internal_error);
6904+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_bc), torrent::internal_error);
6905+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_1), torrent::internal_error);
6906+}
6907diff --git a/test/torrent/net/test_socket_address.h b/test/torrent/net/test_socket_address.h
6908new file mode 100644
6909index 00000000..6157f366
6910--- /dev/null
6911+++ b/test/torrent/net/test_socket_address.h
6912@@ -0,0 +1,43 @@
6913+#include <cppunit/extensions/HelperMacros.h>
6914+
6915+class test_socket_address : public CppUnit::TestFixture {
6916+ CPPUNIT_TEST_SUITE(test_socket_address);
6917+
6918+ CPPUNIT_TEST(test_sa_is_any);
6919+ CPPUNIT_TEST(test_sa_is_broadcast);
6920+
6921+ CPPUNIT_TEST(test_make);
6922+
6923+ CPPUNIT_TEST(test_sin_from_sa);
6924+ CPPUNIT_TEST(test_sin6_from_sa);
6925+
6926+ CPPUNIT_TEST(test_sa_equal);
6927+ CPPUNIT_TEST(test_sa_equal_addr);
6928+ CPPUNIT_TEST(test_sa_copy);
6929+ CPPUNIT_TEST(test_sa_copy_addr);
6930+
6931+ CPPUNIT_TEST(test_sa_from_v4mapped);
6932+ CPPUNIT_TEST(test_sa_to_v4mapped);
6933+
6934+ CPPUNIT_TEST_SUITE_END();
6935+
6936+public:
6937+ void setUp() {}
6938+ void tearDown() {}
6939+
6940+ void test_sa_is_any();
6941+ void test_sa_is_broadcast();
6942+
6943+ void test_make();
6944+
6945+ void test_sin_from_sa();
6946+ void test_sin6_from_sa();
6947+
6948+ void test_sa_equal();
6949+ void test_sa_equal_addr();
6950+ void test_sa_copy();
6951+ void test_sa_copy_addr();
6952+
6953+ void test_sa_from_v4mapped();
6954+ void test_sa_to_v4mapped();
6955+};
6956diff --git a/test/torrent/net/test_socket_address_key.cc b/test/torrent/net/test_socket_address_key.cc
6957deleted file mode 100644
6958index 7892e730..00000000
6959--- a/test/torrent/net/test_socket_address_key.cc
6960+++ /dev/null
6961@@ -1,87 +0,0 @@
6962-#include "config.h"
6963-
6964-#include lt_tr1_functional
6965-#include <sys/types.h>
6966-#include <sys/socket.h>
6967-
6968-#include "test_socket_address_key.h"
6969-
6970-#include "torrent/utils/net.h"
6971-#include "torrent/net/socket_address_key.h"
6972-
6973-CPPUNIT_TEST_SUITE_REGISTRATION(test_socket_address_key);
6974-
6975-// TODO: Move into a test utilities header:
6976-
6977-typedef std::function<struct addrinfo* ()> addrinfo_ftor;
6978-
6979-static torrent::socket_address_key
6980-test_create_valid(const char* hostname, addrinfo_ftor ftor) {
6981- struct addrinfo* addr_info;
6982-
6983- try {
6984- addr_info = ftor();
6985- } catch (torrent::address_info_error& e) {
6986- CPPUNIT_ASSERT_MESSAGE("Caught address_info_error for '" + std::string(hostname) + "'", false);
6987- }
6988-
6989- CPPUNIT_ASSERT_MESSAGE("test_create_valid could not find '" + std::string(hostname) + "'",
6990- addr_info != NULL);
6991-
6992- torrent::socket_address_key sock_key = torrent::socket_address_key::from_sockaddr(addr_info->ai_addr);
6993-
6994- CPPUNIT_ASSERT_MESSAGE("test_create_valid failed to create valid socket_address_key for '" + std::string(hostname) + "'",
6995- sock_key.is_valid());
6996-
6997- return sock_key;
6998-}
6999-
7000-static bool
7001-test_create_throws(const char* hostname, addrinfo_ftor ftor) {
7002- try {
7003- ftor();
7004-
7005- return false;
7006- } catch (torrent::address_info_error& e) {
7007- return true;
7008- }
7009-}
7010-
7011-static torrent::socket_address_key
7012-test_create_inet(const char* hostname) {
7013- return test_create_valid(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET, 0));
7014-}
7015-
7016-static bool
7017-test_create_inet_throws(const char* hostname) {
7018- return test_create_throws(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET, 0));
7019-}
7020-
7021-static torrent::socket_address_key
7022-test_create_inet6(const char* hostname) {
7023- return test_create_valid(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET6, 0));
7024-}
7025-
7026-static bool
7027-test_create_inet6_throws(const char* hostname) {
7028- return test_create_throws(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET6, 0));
7029-}
7030-
7031-//
7032-// Basic tests:
7033-//
7034-
7035-void
7036-test_socket_address_key::test_basic() {
7037- CPPUNIT_ASSERT(test_create_inet("1.1.1.1").is_valid());
7038- CPPUNIT_ASSERT(test_create_inet_throws("1.1.1.300"));
7039-
7040- CPPUNIT_ASSERT(test_create_inet6("ff01::1").is_valid());
7041- CPPUNIT_ASSERT(test_create_inet6("2001:0db8:85a3:0000:0000:8a2e:0370:7334").is_valid());
7042- CPPUNIT_ASSERT(test_create_inet6("2001:db8:a::123").is_valid());
7043-
7044- CPPUNIT_ASSERT(test_create_inet6_throws("2001:db8:a::22123"));
7045-}
7046-
7047-
7048-// Test lexical comparison:
7049diff --git a/test/torrent/object_stream_test.cc b/test/torrent/object_stream_test.cc
7050index c8a17049..5ad0c23e 100644
7051--- a/test/torrent/object_stream_test.cc
7052+++ b/test/torrent/object_stream_test.cc
7053@@ -1,10 +1,8 @@
7054 #include "config.h"
7055
7056-#define __STDC_CONSTANT_MACROS
7057-
7058 #include <iostream>
7059 #include <sstream>
7060-#include <inttypes.h>
7061+#include <cinttypes>
7062 #include <torrent/object.h>
7063
7064 #include "object_stream_test.h"
7065diff --git a/test/torrent/tracker_controller_features.cc b/test/torrent/tracker_controller_features.cc
7066index 63f163f5..0a6a57d6 100644
7067--- a/test/torrent/tracker_controller_features.cc
7068+++ b/test/torrent/tracker_controller_features.cc
7069@@ -1,7 +1,7 @@
7070 #include "config.h"
7071
7072+#include <functional>
7073 #include <iostream>
7074-#include lt_tr1_functional
7075
7076 #include "rak/priority_queue_default.h"
7077
7078diff --git a/test/torrent/tracker_controller_requesting.cc b/test/torrent/tracker_controller_requesting.cc
7079index 5bc25169..92e664b3 100644
7080--- a/test/torrent/tracker_controller_requesting.cc
7081+++ b/test/torrent/tracker_controller_requesting.cc
7082@@ -1,7 +1,7 @@
7083 #include "config.h"
7084
7085+#include <functional>
7086 #include <iostream>
7087-#include lt_tr1_functional
7088
7089 #include "rak/priority_queue_default.h"
7090
7091diff --git a/test/torrent/tracker_controller_test.cc b/test/torrent/tracker_controller_test.cc
7092index 823a9d34..9406c99e 100644
7093--- a/test/torrent/tracker_controller_test.cc
7094+++ b/test/torrent/tracker_controller_test.cc
7095@@ -1,7 +1,7 @@
7096 #include "config.h"
7097
7098+#include <functional>
7099 #include <iostream>
7100-#include lt_tr1_functional
7101
7102 #include "rak/priority_queue_default.h"
7103
7104diff --git a/test/torrent/tracker_list_features_test.cc b/test/torrent/tracker_list_features_test.cc
7105index 57c05f40..5257b1a7 100644
7106--- a/test/torrent/tracker_list_features_test.cc
7107+++ b/test/torrent/tracker_list_features_test.cc
7108@@ -1,6 +1,6 @@
7109 #include "config.h"
7110
7111-#include lt_tr1_functional
7112+#include <functional>
7113
7114 #include "torrent/http.h"
7115 #include "net/address_list.h"
7116diff --git a/test/torrent/utils/directory_events_test.cc b/test/torrent/utils/directory_events_test.cc
7117index 2cea5ab5..b97fd1d4 100644
7118--- a/test/torrent/utils/directory_events_test.cc
7119+++ b/test/torrent/utils/directory_events_test.cc
7120@@ -1,6 +1,6 @@
7121 #include "config.h"
7122
7123-#include <tr1/functional>
7124+#include <functional>
7125 #include <torrent/exceptions.h>
7126 #include <torrent/utils/directory_events.h>
7127
7128@@ -8,8 +8,6 @@
7129
7130 CPPUNIT_TEST_SUITE_REGISTRATION(utils_directory_events_test);
7131
7132-namespace tr1 { using namespace std::tr1; }
7133-
7134 void
7135 utils_directory_events_test::setUp() {
7136 }
7137diff --git a/test/torrent/utils/log_buffer_test.h b/test/torrent/utils/log_buffer_test.h
7138deleted file mode 100644
7139index f2824594..00000000
7140--- a/test/torrent/utils/log_buffer_test.h
7141+++ /dev/null
7142@@ -1,17 +0,0 @@
7143-#include <cppunit/extensions/HelperMacros.h>
7144-
7145-#include "torrent/utils/log_buffer.h"
7146-
7147-class utils_log_buffer_test : public CppUnit::TestFixture {
7148- CPPUNIT_TEST_SUITE(utils_log_buffer_test);
7149- CPPUNIT_TEST(test_basic);
7150- CPPUNIT_TEST(test_timestamps);
7151- CPPUNIT_TEST_SUITE_END();
7152-
7153-public:
7154- void setUp();
7155- void tearDown();
7156-
7157- void test_basic();
7158- void test_timestamps();
7159-};
7160diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
7161index 9f975636..8cc00ef8 100644
7162--- a/test/torrent/utils/log_test.cc
7163+++ b/test/torrent/utils/log_test.cc
7164@@ -3,8 +3,9 @@
7165 #include <algorithm>
7166 #include <cstring>
7167 #include <fstream>
7168+#include <functional>
7169 #include <iostream>
7170-#include lt_tr1_functional
7171+
7172 #include <torrent/exceptions.h>
7173 #include <torrent/utils/log.h>
7174
7175@@ -37,6 +38,7 @@ void
7176 utils_log_test::setUp() {
7177 // Don't initialize since this creates the group->child connections.
7178 // torrent::log_initialize();
7179+ torrent::log_cleanup();
7180 }
7181
7182 void
7183diff --git a/test/torrent/utils/net_test.cc b/test/torrent/utils/net_test.cc
7184deleted file mode 100644
7185index d136e869..00000000
7186--- a/test/torrent/utils/net_test.cc
7187+++ /dev/null
7188@@ -1,32 +0,0 @@
7189-#include "config.h"
7190-
7191-#include <torrent/exceptions.h>
7192-#include <torrent/utils/net.h>
7193-
7194-#include "net_test.h"
7195-
7196-CPPUNIT_TEST_SUITE_REGISTRATION(utils_net_test);
7197-
7198-static void inc_value(int* value) { (*value)++; }
7199-
7200-#define LTUNIT_AI_CALL(lt_ai, lt_flags) { \
7201- int test_value = 0; \
7202- CPPUNIT_ASSERT(torrent::address_info_call(ai, 0, std::bind(&inc_value, &test_value))); \
7203- CPPUNIT_ASSERT(test_value); } \
7204-
7205-void
7206-utils_net_test::setUp() {
7207-}
7208-
7209-void
7210-utils_net_test::tearDown() {
7211-}
7212-
7213-void
7214-utils_net_test::test_basic() {
7215- addrinfo* ai = torrent::address_info_lookup("localhost", AF_INET, SOCK_STREAM);
7216-
7217- LTUNIT_AI_CALL(ai, 0);
7218-
7219- torrent::address_info_free(ai);
7220-}
7221diff --git a/test/torrent/utils/net_test.h b/test/torrent/utils/net_test.h
7222deleted file mode 100644
7223index e538ab39..00000000
7224--- a/test/torrent/utils/net_test.h
7225+++ /dev/null
7226@@ -1,15 +0,0 @@
7227-#include <cppunit/extensions/HelperMacros.h>
7228-
7229-#include "torrent/utils/net.h"
7230-
7231-class utils_net_test : public CppUnit::TestFixture {
7232- CPPUNIT_TEST_SUITE(utils_net_test);
7233- CPPUNIT_TEST(test_basic);
7234- CPPUNIT_TEST_SUITE_END();
7235-
7236-public:
7237- void setUp();
7238- void tearDown();
7239-
7240- void test_basic();
7241-};
7242diff --git a/test/torrent/utils/option_strings_test.cc b/test/torrent/utils/option_strings_test.cc
7243index c6302f98..a9bdcc89 100644
7244--- a/test/torrent/utils/option_strings_test.cc
7245+++ b/test/torrent/utils/option_strings_test.cc
7246@@ -1,8 +1,9 @@
7247 #include "config.h"
7248
7249 #include <fstream>
7250+#include <functional>
7251 #include <iostream>
7252-#include lt_tr1_functional
7253+
7254 #include <torrent/exceptions.h>
7255 #include <torrent/utils/option_strings.h>
7256
7257diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc
7258index d6b8d11d..87424d62 100644
7259--- a/test/torrent/utils/test_extents.cc
7260+++ b/test/torrent/utils/test_extents.cc
7261@@ -2,7 +2,7 @@
7262
7263 #include "test_extents.h"
7264
7265-#include <inttypes.h>
7266+#include <cinttypes>
7267 #include <iostream>
7268 #include <torrent/utils/extents.h>
7269
7270diff --git a/test/torrent/utils/log_buffer_test.cc b/test/torrent/utils/test_log_buffer.cc
7271similarity index 86%
7272rename from test/torrent/utils/log_buffer_test.cc
7273rename to test/torrent/utils/test_log_buffer.cc
7274index a0ede0a0..a56a5365 100644
7275--- a/test/torrent/utils/log_buffer_test.cc
7276+++ b/test/torrent/utils/test_log_buffer.cc
7277@@ -1,23 +1,23 @@
7278 #include "config.h"
7279
7280-#include <torrent/utils/log_buffer.h>
7281+#include "test_log_buffer.h"
7282
7283 #include "globals.h"
7284-#include "log_buffer_test.h"
7285+#include <torrent/utils/log_buffer.h>
7286
7287-CPPUNIT_TEST_SUITE_REGISTRATION(utils_log_buffer_test);
7288+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log_buffer, "torrent/utils");
7289
7290 void
7291-utils_log_buffer_test::setUp() {
7292+test_log_buffer::setUp() {
7293 torrent::cachedTime = rak::timer::from_seconds(1000);
7294 }
7295
7296 void
7297-utils_log_buffer_test::tearDown() {
7298+test_log_buffer::tearDown() {
7299 }
7300
7301 void
7302-utils_log_buffer_test::test_basic() {
7303+test_log_buffer::test_basic() {
7304 torrent::log_buffer log;
7305
7306 log.lock();
7307@@ -44,7 +44,7 @@ utils_log_buffer_test::test_basic() {
7308 }
7309
7310 void
7311-utils_log_buffer_test::test_timestamps() {
7312+test_log_buffer::test_timestamps() {
7313 torrent::log_buffer log;
7314
7315 log.lock_and_push_log("foobar", 6, 0);
7316diff --git a/test/torrent/utils/test_log_buffer.h b/test/torrent/utils/test_log_buffer.h
7317new file mode 100644
7318index 00000000..290df4c1
7319--- /dev/null
7320+++ b/test/torrent/utils/test_log_buffer.h
7321@@ -0,0 +1,17 @@
7322+#include "helpers/test_fixture.h"
7323+
7324+class test_log_buffer : public test_fixture {
7325+ CPPUNIT_TEST_SUITE(test_log_buffer);
7326+
7327+ CPPUNIT_TEST(test_basic);
7328+ CPPUNIT_TEST(test_timestamps);
7329+
7330+ CPPUNIT_TEST_SUITE_END();
7331+
7332+public:
7333+ void setUp();
7334+ void tearDown();
7335+
7336+ void test_basic();
7337+ void test_timestamps();
7338+};
7339diff --git a/test/torrent/utils/test_uri_parser.cc b/test/torrent/utils/test_uri_parser.cc
7340index c3b46eef..1f4bebe8 100644
7341--- a/test/torrent/utils/test_uri_parser.cc
7342+++ b/test/torrent/utils/test_uri_parser.cc
7343@@ -2,7 +2,7 @@
7344
7345 #include "test_uri_parser.h"
7346
7347-#include <inttypes.h>
7348+#include <cinttypes>
7349 #include <iostream>
7350 #include <torrent/utils/uri_parser.h>
7351
7352diff --git a/test/torrent/utils/thread_base_test.cc b/test/torrent/utils/thread_base_test.cc
7353index 5cb7553f..8366c9ba 100644
7354--- a/test/torrent/utils/thread_base_test.cc
7355+++ b/test/torrent/utils/thread_base_test.cc
7356@@ -1,7 +1,8 @@
7357 #include "config.h"
7358
7359+#include <functional>
7360 #include <unistd.h>
7361-#include lt_tr1_functional
7362+
7363 #include <torrent/exceptions.h>
7364 #include <torrent/poll_select.h>
7365 #include <torrent/utils/thread_base.h>
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch
new file mode 100644
index 0000000000..d81548ceb7
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch
@@ -0,0 +1,26 @@
1From b656a77864bd322d69522f1f9d922404066e5a7c Mon Sep 17 00:00:00 2001
2From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
3Date: Mon, 21 Oct 2019 09:32:15 +0200
4Subject: [PATCH] libtorrent.pc.in: add Libs.Private (#202)
5
6Add Libs.Private: -lz so applications that want to link statically with
7libtorrent (such as rtorrent) will know that they must link with -lz
8
9Fixes:
10 - http://autobuild.buildroot.org/results/075598e1699c2ac20a4dfbcb5695bbb7343f9a86
11
12Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
13---
14 libtorrent.pc.in | 1 +
15 1 file changed, 1 insertion(+)
16
17diff --git a/libtorrent.pc.in b/libtorrent.pc.in
18index cf6612bc..6108f7e9 100644
19--- a/libtorrent.pc.in
20+++ b/libtorrent.pc.in
21@@ -7,4 +7,5 @@ Name: libtorrent
22 Description: A BitTorrent library
23 Version: @VERSION@
24 Libs: -L${libdir} -ltorrent
25+Libs.Private: -lz
26 Cflags: -I${includedir}
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch
new file mode 100644
index 0000000000..59cf76cad4
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch
@@ -0,0 +1,27 @@
1From 7c80dc3e3a47dd996ca0554fce4f69d16761a9c9 Mon Sep 17 00:00:00 2001
2From: Tadej Obrstar <tadej.obrstar@gmail.com>
3Date: Sun, 1 Dec 2019 06:59:25 +0100
4Subject: [PATCH] Fix for inotify missing quickly renamed files (#203)
5
6---
7 src/torrent/utils/directory_events.cc | 7 +++++--
8 1 file changed, 5 insertions(+), 2 deletions(-)
9
10diff --git a/src/torrent/utils/directory_events.cc b/src/torrent/utils/directory_events.cc
11index 5d789f4e..8dcc2a61 100644
12--- a/src/torrent/utils/directory_events.cc
13+++ b/src/torrent/utils/directory_events.cc
14@@ -154,8 +154,11 @@ directory_events::event_read() {
15 wd_list::const_iterator itr = std::find_if(m_wd_list.begin(), m_wd_list.end(),
16 std::bind(&watch_descriptor::compare_desc, std::placeholders::_1, event->wd));
17
18- if (itr != m_wd_list.end())
19- itr->slot(itr->path + event->name);
20+ if (itr != m_wd_list.end()) {
21+ std::string sname(event->name);
22+ if((sname.substr(sname.find_last_of(".") ) == ".torrent"))
23+ itr->slot(itr->path + event->name);
24+ }
25
26 event = (struct inotify_event*)(next_event);
27 }
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch
new file mode 100644
index 0000000000..5b26f959fa
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch
@@ -0,0 +1,470 @@
1From 81897862edea81e9620493c473f488d1820bcf93 Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Tue, 3 Dec 2019 21:53:48 +0900
4Subject: [PATCH] Fix compiler warnings. (#204)
5
6---
7 configure.ac | 6 ++-
8 scripts/ax_execinfo.m4 | 67 +++++++++++++++++++++++++++++++
9 scripts/common.m4 | 15 -------
10 scripts/rak_execinfo.m4 | 11 +++++
11 src/torrent/exceptions.cc | 4 +-
12 test/Makefile.am | 15 ++-----
13 test/helpers/expect_fd.h | 8 ++--
14 test/helpers/mock_compare.h | 6 +--
15 test/helpers/progress_listener.cc | 3 +-
16 test/main.cc | 4 +-
17 test/net/Makefile.am | 40 ++++++++++++++++++
18 test/torrent/net/Makefile.am | 44 ++++++++++++++++++++
19 test/torrent/net/test_fd.cc | 48 +++++++++++-----------
20 13 files changed, 207 insertions(+), 64 deletions(-)
21 create mode 100644 scripts/ax_execinfo.m4
22 create mode 100644 scripts/rak_execinfo.m4
23 create mode 100644 test/net/Makefile.am
24 create mode 100644 test/torrent/net/Makefile.am
25
26diff --git a/configure.ac b/configure.ac
27index 620ca552..b6708366 100644
28--- a/configure.ac
29+++ b/configure.ac
30@@ -33,6 +33,7 @@ RAK_CHECK_CXXFLAGS
31 RAK_ENABLE_DEBUG
32 RAK_ENABLE_EXTRA_DEBUG
33 RAK_ENABLE_WERROR
34+RAK_DISABLE_BACKTRACE
35
36 RAK_CHECK_CXX11
37
38@@ -57,8 +58,8 @@ TORRENT_WITH_INOTIFY
39
40 CC_ATTRIBUTE_VISIBILITY
41
42-AX_PTHREAD
43 AX_CHECK_ZLIB
44+AX_PTHREAD
45
46 PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
47
48@@ -74,7 +75,6 @@ AC_CHECK_FUNCS(posix_memalign)
49 TORRENT_CHECK_MADVISE()
50 TORRENT_CHECK_CACHELINE()
51 TORRENT_CHECK_POPCOUNT()
52-TORRENT_CHECK_EXECINFO()
53 TORRENT_CHECK_PTHREAD_SETNAME_NP()
54 TORRENT_MINCORE()
55
56@@ -111,4 +111,6 @@ AC_OUTPUT([
57 src/tracker/Makefile
58 src/utils/Makefile
59 test/Makefile
60+ test/torrent/net/Makefile
61+ test/net/Makefile
62 ])
63diff --git a/scripts/ax_execinfo.m4 b/scripts/ax_execinfo.m4
64new file mode 100644
65index 00000000..0ff5fc0e
66--- /dev/null
67+++ b/scripts/ax_execinfo.m4
68@@ -0,0 +1,67 @@
69+# ===========================================================================
70+# https://www.gnu.org/software/autoconf-archive/ax_execinfo.html
71+# ===========================================================================
72+#
73+# SYNOPSIS
74+#
75+# AX_EXECINFO([ACTION-IF-EXECINFO-H-IS-FOUND], [ACTION-IF-EXECINFO-H-IS-NOT-FOUND], [ADDITIONAL-TYPES-LIST])
76+#
77+# DESCRIPTION
78+#
79+# Checks for execinfo.h header and if the len parameter/return type can be
80+# found from a list, also define backtrace_size_t to that type.
81+#
82+# By default the list of types to try contains int and size_t, but should
83+# some yet undiscovered system use e.g. unsigned, the 3rd argument can be
84+# used for extensions. I'd like to hear of further suggestions.
85+#
86+# Executes ACTION-IF-EXECINFO-H-IS-FOUND when present and the execinfo.h
87+# header is found or ACTION-IF-EXECINFO-H-IS-NOT-FOUND in case the header
88+# seems unavailable.
89+#
90+# Also adds -lexecinfo to LIBS on BSD if needed.
91+#
92+# LICENSE
93+#
94+# Copyright (c) 2014 Thomas Jahns <jahns@dkrz.de>
95+#
96+# Copying and distribution of this file, with or without modification, are
97+# permitted in any medium without royalty provided the copyright notice
98+# and this notice are preserved. This file is offered as-is, without any
99+# warranty.
100+
101+#serial 2
102+
103+AC_DEFUN([AX_EXECINFO],
104+ [AC_CHECK_HEADERS([execinfo.h])
105+ AS_IF([test x"$ac_cv_header_execinfo_h" = xyes],
106+ [AC_CACHE_CHECK([size parameter type for backtrace()],
107+ [ax_cv_proto_backtrace_type],
108+ [AC_LANG_PUSH([C])
109+ for ax_cv_proto_backtrace_type in size_t int m4_ifnblank([$3],[$3 ])none; do
110+ AS_IF([test "${ax_cv_proto_backtrace_type}" = none],
111+ [ax_cv_proto_backtrace_type= ; break])
112+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
113+#include <execinfo.h>
114+extern
115+${ax_cv_proto_backtrace_type} backtrace(void **addrlist, ${ax_cv_proto_backtrace_type} len);
116+char **backtrace_symbols(void *const *buffer, ${ax_cv_proto_backtrace_type} size);
117+])],
118+ [break])
119+ done
120+ AC_LANG_POP([C])])])
121+ AS_IF([test x${ax_cv_proto_backtrace_type} != x],
122+ [AC_DEFINE_UNQUOTED([backtrace_size_t], [$ax_cv_proto_backtrace_type],
123+ [Defined to return type of backtrace().])])
124+ AC_SEARCH_LIBS([backtrace],[execinfo])
125+ 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],
126+ [AC_DEFINE([HAVE_BACKTRACE],[1],
127+ [Defined if backtrace() could be fully identified.])
128+ ]m4_ifnblank([$1],[$1
129+]),m4_ifnblank([$2],[$2
130+]))])
131+dnl
132+dnl Local Variables:
133+dnl mode: autoconf
134+dnl End:
135+dnl
136diff --git a/scripts/common.m4 b/scripts/common.m4
137index b6d051f5..55e8d66e 100644
138--- a/scripts/common.m4
139+++ b/scripts/common.m4
140@@ -150,21 +150,6 @@ dnl Need to fix this so that it uses the stuff defined by the system.
141 ])
142 ])
143
144-AC_DEFUN([TORRENT_CHECK_EXECINFO], [
145- AC_MSG_CHECKING(for execinfo.h)
146-
147- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
148- #include <execinfo.h>
149- int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
150- ])],
151- [
152- AC_MSG_RESULT(yes)
153- AC_DEFINE(USE_EXECINFO, 1, Use execinfo.h)
154- ], [
155- AC_MSG_RESULT(no)
156- ])
157-])
158-
159 AC_DEFUN([TORRENT_CHECK_ALIGNED], [
160 AC_MSG_CHECKING(the byte alignment)
161
162diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4
163new file mode 100644
164index 00000000..c1d9b2f8
165--- /dev/null
166+++ b/scripts/rak_execinfo.m4
167@@ -0,0 +1,11 @@
168+AC_DEFUN([RAK_DISABLE_BACKTRACE], [
169+ AC_ARG_ENABLE(backtrace,
170+ AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]),
171+ [
172+ if test "$enableval" = "yes"; then
173+ AX_EXECINFO
174+ fi
175+ ],[
176+ AX_EXECINFO
177+ ])
178+])
179diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc
180index 2aeca1d7..f834f9fa 100644
181--- a/src/torrent/exceptions.cc
182+++ b/src/torrent/exceptions.cc
183@@ -42,7 +42,7 @@
184 #include <sstream>
185 #include <unistd.h>
186
187-#ifdef USE_EXECINFO
188+#ifdef HAVE_BACKTRACE
189 #include <execinfo.h>
190 #endif
191
192@@ -75,7 +75,7 @@ internal_error::initialize(const std::string& msg) {
193
194 std::stringstream output;
195
196-#ifdef USE_EXECINFO
197+#ifdef HAVE_BACKTRACE
198 void* stackPtrs[20];
199
200 // Print the stack and exit.
201diff --git a/test/Makefile.am b/test/Makefile.am
202index b60a86a6..23b260e4 100644
203--- a/test/Makefile.am
204+++ b/test/Makefile.am
205@@ -1,3 +1,5 @@
206+SUBDIRS = torrent/net net
207+
208 TESTS = LibTorrentTest
209 AUTOMAKE_OPTIONS = subdir-objects
210
211@@ -43,19 +45,9 @@ LibTorrentTest_SOURCES = \
212 data/hash_queue_test.cc \
213 data/hash_queue_test.h \
214 \
215- net/test_socket_listen.cc \
216- net/test_socket_listen.h \
217- \
218 protocol/test_request_list.cc \
219 protocol/test_request_list.h \
220 \
221- torrent/net/test_address_info.cc \
222- torrent/net/test_address_info.h \
223- torrent/net/test_fd.cc \
224- torrent/net/test_fd.h \
225- torrent/net/test_socket_address.cc \
226- torrent/net/test_socket_address.h \
227- \
228 torrent/utils/log_test.cc \
229 torrent/utils/log_test.h \
230 torrent/utils/option_strings_test.cc \
231@@ -97,9 +89,10 @@ LibTorrentTest_SOURCES = \
232 torrent/tracker_timeout_test.h \
233 tracker/tracker_http_test.cc \
234 tracker/tracker_http_test.h \
235+ \
236 main.cc
237
238 LibTorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
239-LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
240+LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
241
242 AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src
243diff --git a/test/helpers/expect_fd.h b/test/helpers/expect_fd.h
244index 178cbabc..cc77c34a 100644
245--- a/test/helpers/expect_fd.h
246+++ b/test/helpers/expect_fd.h
247@@ -18,15 +18,15 @@ sap_cache_copy_addr_c_ptr(sap_cache_type& sap_cache, const torrent::c_sa_unique_
248
249 inline void
250 expect_event_open_re(int idx) {
251- mock_expect(&torrent::poll_event_open, mock_compare_map<torrent::Event>::begin_pointer + idx);
252- mock_expect(&torrent::poll_event_insert_read, mock_compare_map<torrent::Event>::begin_pointer + idx);
253- mock_expect(&torrent::poll_event_insert_error, mock_compare_map<torrent::Event>::begin_pointer + idx);
254+ mock_expect(&torrent::poll_event_open, mock_compare_map<torrent::Event>::begin_pointer() + idx);
255+ mock_expect(&torrent::poll_event_insert_read, mock_compare_map<torrent::Event>::begin_pointer() + idx);
256+ mock_expect(&torrent::poll_event_insert_error, mock_compare_map<torrent::Event>::begin_pointer() + idx);
257 }
258
259 inline void
260 expect_event_closed_fd(int idx, int fd) {
261 mock_expect(&torrent::fd__close, 0, fd);
262- mock_expect(&torrent::poll_event_closed, mock_compare_map<torrent::Event>::begin_pointer + idx);
263+ mock_expect(&torrent::poll_event_closed, mock_compare_map<torrent::Event>::begin_pointer() + idx);
264 }
265
266 inline void
267diff --git a/test/helpers/mock_compare.h b/test/helpers/mock_compare.h
268index 3ea90305..3cc8d075 100644
269--- a/test/helpers/mock_compare.h
270+++ b/test/helpers/mock_compare.h
271@@ -34,11 +34,11 @@ template <typename T>
272 struct mock_compare_map {
273 typedef std::map<const T*, const T*> values_type;
274
275- constexpr static T* begin_pointer = reinterpret_cast<T*>(0x1000);
276- constexpr static T* end_pointer = reinterpret_cast<T*>(0x2000);
277+ static T* begin_pointer() { return reinterpret_cast<T*>(0x1000); }
278+ static T* end_pointer() { return reinterpret_cast<T*>(0x2000); }
279
280 static bool is_key(const T* k) {
281- return k >= begin_pointer && k < end_pointer;
282+ return k >= begin_pointer() && k < end_pointer();
283 }
284
285 static bool has_key(const T* k) {
286diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc
287index 02803ffc..c2b60bcd 100644
288--- a/test/helpers/progress_listener.cc
289+++ b/test/helpers/progress_listener.cc
290@@ -54,7 +54,8 @@ void
291 progress_listener::startSuite(CppUnit::Test *suite) {
292 m_test_path.push_back(suite);
293
294- std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl;
295+ if (suite->countTestCases() > 0)
296+ std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl;
297 }
298
299 void
300diff --git a/test/main.cc b/test/main.cc
301index da93fead..e8a00e1f 100644
302--- a/test/main.cc
303+++ b/test/main.cc
304@@ -12,7 +12,7 @@
305 #include <cppunit/extensions/TestFactoryRegistry.h>
306 #include <cppunit/ui/text/TestRunner.h>
307
308-#ifdef USE_EXECINFO
309+#ifdef HAVE_BACKTRACE
310 #include <execinfo.h>
311 #endif
312
313@@ -29,7 +29,7 @@ do_test_panic(int signum) {
314
315 std::cout << std::endl << std::endl << "Caught " << strsignal(signum) << ", dumping stack:" << std::endl << std::endl;
316
317-#ifdef USE_EXECINFO
318+#ifdef HAVE_BACKTRACE
319 void* stackPtrs[20];
320
321 // Print the stack and exit.
322diff --git a/test/net/Makefile.am b/test/net/Makefile.am
323new file mode 100644
324index 00000000..bb951814
325--- /dev/null
326+++ b/test/net/Makefile.am
327@@ -0,0 +1,40 @@
328+TESTS = LibTorrentTestNet
329+AUTOMAKE_OPTIONS = subdir-objects
330+
331+check_PROGRAMS = $(TESTS)
332+LibTorrentTestNet_LDADD = \
333+ ../../src/libtorrent.la \
334+ ../../src/torrent/libsub_torrent.la \
335+ ../../src/torrent/data/libsub_torrentdata.la \
336+ ../../src/torrent/download/libsub_torrentdownload.la \
337+ ../../src/torrent/peer/libsub_torrentpeer.la \
338+ ../../src/data/libsub_data.la \
339+ ../../src/dht/libsub_dht.la \
340+ ../../src/net/libsub_net.la \
341+ ../../src/protocol/libsub_protocol.la \
342+ ../../src/download/libsub_download.la \
343+ ../../src/tracker/libsub_tracker.la \
344+ ../../src/utils/libsub_utils.la \
345+ ../../src/torrent/utils/libsub_torrentutils.la
346+
347+LibTorrentTestNet_SOURCES = \
348+ ../helpers/expect_fd.h \
349+ ../helpers/expect_utils.h \
350+ ../helpers/mock_compare.h \
351+ ../helpers/mock_function.cc \
352+ ../helpers/mock_function.h \
353+ ../helpers/network.h \
354+ ../helpers/progress_listener.cc \
355+ ../helpers/progress_listener.h \
356+ ../helpers/test_fixture.cc \
357+ ../helpers/test_fixture.h \
358+ \
359+ test_socket_listen.cc \
360+ test_socket_listen.h \
361+ \
362+ ../main.cc
363+
364+LibTorrentTestNet_CXXFLAGS = $(CPPUNIT_CFLAGS)
365+LibTorrentTestNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl
366+
367+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test
368diff --git a/test/torrent/net/Makefile.am b/test/torrent/net/Makefile.am
369new file mode 100644
370index 00000000..8a531cc1
371--- /dev/null
372+++ b/test/torrent/net/Makefile.am
373@@ -0,0 +1,44 @@
374+TESTS = LibTorrentTestTorrentNet
375+AUTOMAKE_OPTIONS = subdir-objects
376+
377+check_PROGRAMS = $(TESTS)
378+LibTorrentTestTorrentNet_LDADD = \
379+ ../../../src/libtorrent.la \
380+ ../../../src/torrent/libsub_torrent.la \
381+ ../../../src/torrent/data/libsub_torrentdata.la \
382+ ../../../src/torrent/download/libsub_torrentdownload.la \
383+ ../../../src/torrent/peer/libsub_torrentpeer.la \
384+ ../../../src/data/libsub_data.la \
385+ ../../../src/dht/libsub_dht.la \
386+ ../../../src/net/libsub_net.la \
387+ ../../../src/protocol/libsub_protocol.la \
388+ ../../../src/download/libsub_download.la \
389+ ../../../src/tracker/libsub_tracker.la \
390+ ../../../src/utils/libsub_utils.la \
391+ ../../../src/torrent/utils/libsub_torrentutils.la
392+
393+LibTorrentTestTorrentNet_SOURCES = \
394+ ../../helpers/expect_fd.h \
395+ ../../helpers/expect_utils.h \
396+ ../../helpers/mock_compare.h \
397+ ../../helpers/mock_function.cc \
398+ ../../helpers/mock_function.h \
399+ ../../helpers/network.h \
400+ ../../helpers/progress_listener.cc \
401+ ../../helpers/progress_listener.h \
402+ ../../helpers/test_fixture.cc \
403+ ../../helpers/test_fixture.h \
404+ \
405+ test_address_info.cc \
406+ test_address_info.h \
407+ test_fd.cc \
408+ test_fd.h \
409+ test_socket_address.cc \
410+ test_socket_address.h \
411+ \
412+ ../../main.cc
413+
414+LibTorrentTestTorrentNet_CXXFLAGS = $(CPPUNIT_CFLAGS)
415+LibTorrentTestTorrentNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl
416+
417+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test
418diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc
419index 3cab0c5e..5e56f0f3 100644
420--- a/test/torrent/net/test_fd.cc
421+++ b/test/torrent/net/test_fd.cc
422@@ -1,24 +1,24 @@
423-#include "config.h"
424-
425-#include "test_fd.h"
426-
427-#include <torrent/net/fd.h>
428-
429-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
430-
431-void
432-test_fd::test_valid_flags() {
433- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
434- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
435- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
436- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
437- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
438-
439- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
440- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
441-
442- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
443- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
444- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all)));
445- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132)));
446-}
447+#include "config.h"
448+
449+#include "test_fd.h"
450+
451+#include <torrent/net/fd.h>
452+
453+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
454+
455+void
456+test_fd::test_valid_flags() {
457+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
458+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
459+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
460+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
461+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
462+
463+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
464+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
465+
466+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
467+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
468+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all)));
469+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132)));
470+}
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch
new file mode 100644
index 0000000000..0ecc0cfe5c
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch
@@ -0,0 +1,33 @@
1From e813c344b1e4aa89288febb2f59109972083f1bb Mon Sep 17 00:00:00 2001
2From: Rosen Penev <rosenp@gmail.com>
3Date: Thu, 5 Dec 2019 01:55:53 -0800
4Subject: [PATCH] Fix log format so GCC can check it. (#205)
5
6---
7 src/torrent/utils/log.cc | 6 +++---
8 1 file changed, 3 insertions(+), 3 deletions(-)
9
10diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
11index b855a2c6..24932996 100644
12--- a/src/torrent/utils/log.cc
13+++ b/src/torrent/utils/log.cc
14@@ -16,6 +16,8 @@
15 #include <functional>
16 #include <memory>
17
18+#define GROUPFMT (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ")
19+
20 namespace torrent {
21
22 struct log_cache_entry {
23@@ -356,9 +358,7 @@ log_gz_file_write(std::shared_ptr<log_gz_output>& outfile, const char* data, siz
24
25 // Normal groups are nul-terminated strings.
26 if (group >= 0) {
27- const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ");
28-
29- int buffer_length = snprintf(buffer, 64, fmt,
30+ int buffer_length = snprintf(buffer, 64, GROUPFMT,
31 cachedTime.seconds(),
32 log_level_char[group % 6]);
33
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch
new file mode 100644
index 0000000000..fa5cb294c2
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch
@@ -0,0 +1,843 @@
1From 7b85e112ac2f59a39afa344148a946553c776142 Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Fri, 6 Dec 2019 00:35:21 +0900
4Subject: [PATCH] Consolidate make script to optimize build. (#206)
5
6---
7 configure.ac | 14 +--
8 src/Makefile.am | 147 ++++++++++++++++++++++++-----
9 src/data/Makefile.am | 28 ------
10 src/dht/Makefile.am | 18 ----
11 src/download/Makefile.am | 19 ----
12 src/net/Makefile.am | 30 ------
13 src/protocol/Makefile.am | 28 ------
14 src/torrent/Makefile.am | 154 ++++++++++++++++++++++++++++---
15 src/torrent/download/Makefile.am | 22 -----
16 src/torrent/net/Makefile.am | 25 -----
17 src/torrent/peer/Makefile.am | 28 ------
18 src/torrent/utils/Makefile.am | 41 --------
19 src/tracker/Makefile.am | 11 ---
20 src/utils/Makefile.am | 14 ---
21 test/Makefile.am | 92 +++++++++++++-----
22 15 files changed, 338 insertions(+), 333 deletions(-)
23 delete mode 100644 src/data/Makefile.am
24 delete mode 100644 src/dht/Makefile.am
25 delete mode 100644 src/download/Makefile.am
26 delete mode 100644 src/net/Makefile.am
27 delete mode 100644 src/protocol/Makefile.am
28 delete mode 100644 src/torrent/download/Makefile.am
29 delete mode 100644 src/torrent/net/Makefile.am
30 delete mode 100644 src/torrent/peer/Makefile.am
31 delete mode 100644 src/torrent/utils/Makefile.am
32 delete mode 100644 src/tracker/Makefile.am
33 delete mode 100644 src/utils/Makefile.am
34
35diff --git a/configure.ac b/configure.ac
36index b6708366..e83710cc 100644
37--- a/configure.ac
38+++ b/configure.ac
39@@ -17,7 +17,7 @@ AC_SUBST(LIBTORRENT_CURRENT)
40 AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO)
41 AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO)
42
43-AM_INIT_AUTOMAKE([serial-tests])
44+AM_INIT_AUTOMAKE([serial-tests subdir-objects])
45 AC_CONFIG_HEADERS(config.h)
46
47 AC_PROG_CXX
48@@ -98,18 +98,6 @@ AC_OUTPUT([
49 Makefile
50 src/Makefile
51 src/torrent/Makefile
52- src/torrent/data/Makefile
53- src/torrent/download/Makefile
54- src/torrent/net/Makefile
55- src/torrent/peer/Makefile
56- src/torrent/utils/Makefile
57- src/data/Makefile
58- src/dht/Makefile
59- src/download/Makefile
60- src/net/Makefile
61- src/protocol/Makefile
62- src/tracker/Makefile
63- src/utils/Makefile
64 test/Makefile
65 test/torrent/net/Makefile
66 test/net/Makefile
67diff --git a/src/Makefile.am b/src/Makefile.am
68index 99aaace0..e96bd74b 100644
69--- a/src/Makefile.am
70+++ b/src/Makefile.am
71@@ -1,30 +1,12 @@
72-SUBDIRS = \
73- torrent \
74- data \
75- dht \
76- download \
77- net \
78- protocol \
79- tracker \
80- utils
81+SUBDIRS = torrent
82
83 lib_LTLIBRARIES = libtorrent.la
84+noinst_LTLIBRARIES = libtorrent_other.la
85
86 libtorrent_la_LDFLAGS = -version-info $(LIBTORRENT_INTERFACE_VERSION_INFO)
87 libtorrent_la_LIBADD = \
88- torrent/libsub_torrent.la \
89- torrent/data/libsub_torrentdata.la \
90- torrent/download/libsub_torrentdownload.la \
91- torrent/net/libsub_torrentnet.la \
92- torrent/peer/libsub_torrentpeer.la \
93- torrent/utils/libsub_torrentutils.la \
94- data/libsub_data.la \
95- dht/libsub_dht.la \
96- download/libsub_download.la \
97- net/libsub_net.la \
98- protocol/libsub_protocol.la \
99- tracker/libsub_tracker.la \
100- utils/libsub_utils.la
101+ torrent/libtorrent_torrent.la \
102+ libtorrent_other.la
103
104 libtorrent_la_SOURCES = \
105 globals.cc \
106@@ -36,4 +18,125 @@ libtorrent_la_SOURCES = \
107 thread_main.cc \
108 thread_main.h
109
110+libtorrent_other_la_SOURCES = \
111+ data/chunk.cc \
112+ data/chunk.h \
113+ data/chunk_handle.h \
114+ data/chunk_iterator.h \
115+ data/chunk_list.cc \
116+ data/chunk_list.h \
117+ data/chunk_list_node.h \
118+ data/chunk_part.cc \
119+ data/chunk_part.h \
120+ data/hash_check_queue.cc \
121+ data/hash_check_queue.h \
122+ data/hash_chunk.cc \
123+ data/hash_chunk.h \
124+ data/hash_queue.cc \
125+ data/hash_queue.h \
126+ data/hash_queue_node.cc \
127+ data/hash_queue_node.h \
128+ data/hash_torrent.cc \
129+ data/hash_torrent.h \
130+ data/memory_chunk.cc \
131+ data/memory_chunk.h \
132+ data/socket_file.cc \
133+ data/socket_file.h \
134+ \
135+ dht/dht_bucket.cc \
136+ dht/dht_bucket.h \
137+ dht/dht_hash_map.h \
138+ dht/dht_node.cc \
139+ dht/dht_node.h \
140+ dht/dht_router.cc \
141+ dht/dht_router.h \
142+ dht/dht_server.cc \
143+ dht/dht_server.h \
144+ dht/dht_tracker.cc \
145+ dht/dht_tracker.h \
146+ dht/dht_transaction.cc \
147+ dht/dht_transaction.h \
148+ \
149+ download/available_list.cc \
150+ download/available_list.h \
151+ download/chunk_selector.cc \
152+ download/chunk_selector.h \
153+ download/chunk_statistics.cc \
154+ download/chunk_statistics.h \
155+ download/delegator.cc \
156+ download/delegator.h \
157+ download/download_constructor.cc \
158+ download/download_constructor.h \
159+ download/download_main.cc \
160+ download/download_main.h \
161+ download/download_wrapper.cc \
162+ download/download_wrapper.h \
163+ \
164+ net/address_list.cc \
165+ net/address_list.h \
166+ net/data_buffer.h \
167+ net/local_addr.cc \
168+ net/local_addr.h \
169+ net/listen.cc \
170+ net/listen.h \
171+ net/protocol_buffer.h \
172+ net/socket_base.cc \
173+ net/socket_base.h \
174+ net/socket_datagram.cc \
175+ net/socket_datagram.h \
176+ net/socket_fd.cc \
177+ net/socket_fd.h \
178+ net/socket_listen.cc \
179+ net/socket_listen.h \
180+ net/socket_set.cc \
181+ net/socket_set.h \
182+ net/socket_stream.cc \
183+ net/socket_stream.h \
184+ net/throttle_internal.cc \
185+ net/throttle_internal.h \
186+ net/throttle_list.cc \
187+ net/throttle_list.h \
188+ net/throttle_node.h \
189+ \
190+ protocol/encryption_info.h \
191+ protocol/extensions.cc \
192+ protocol/extensions.h \
193+ protocol/handshake.cc \
194+ protocol/handshake.h \
195+ protocol/handshake_encryption.cc \
196+ protocol/handshake_encryption.h \
197+ protocol/handshake_manager.cc \
198+ protocol/handshake_manager.h \
199+ protocol/initial_seed.cc \
200+ protocol/initial_seed.h \
201+ protocol/peer_chunks.h \
202+ protocol/peer_connection_base.cc \
203+ protocol/peer_connection_base.h \
204+ protocol/peer_connection_leech.cc \
205+ protocol/peer_connection_leech.h \
206+ protocol/peer_connection_metadata.cc \
207+ protocol/peer_connection_metadata.h \
208+ protocol/peer_factory.cc \
209+ protocol/peer_factory.h \
210+ protocol/protocol_base.h \
211+ protocol/request_list.cc \
212+ protocol/request_list.h \
213+ \
214+ tracker/tracker_dht.cc \
215+ tracker/tracker_dht.h \
216+ tracker/tracker_http.cc \
217+ tracker/tracker_http.h \
218+ tracker/tracker_udp.cc \
219+ tracker/tracker_udp.h \
220+ \
221+ utils/diffie_hellman.cc \
222+ utils/diffie_hellman.h \
223+ utils/instrumentation.cc \
224+ utils/instrumentation.h \
225+ utils/rc4.h \
226+ utils/sha1.h \
227+ utils/sha_fast.cc \
228+ utils/sha_fast.h \
229+ utils/queue_buckets.h
230+
231 AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)
232diff --git a/src/data/Makefile.am b/src/data/Makefile.am
233deleted file mode 100644
234index ef41c9bd..00000000
235--- a/src/data/Makefile.am
236+++ /dev/null
237@@ -1,28 +0,0 @@
238-noinst_LTLIBRARIES = libsub_data.la
239-
240-libsub_data_la_SOURCES = \
241- chunk.cc \
242- chunk.h \
243- chunk_handle.h \
244- chunk_iterator.h \
245- chunk_list.cc \
246- chunk_list.h \
247- chunk_list_node.h \
248- chunk_part.cc \
249- chunk_part.h \
250- hash_check_queue.cc \
251- hash_check_queue.h \
252- hash_chunk.cc \
253- hash_chunk.h \
254- hash_queue.cc \
255- hash_queue.h \
256- hash_queue_node.cc \
257- hash_queue_node.h \
258- hash_torrent.cc \
259- hash_torrent.h \
260- memory_chunk.cc \
261- memory_chunk.h \
262- socket_file.cc \
263- socket_file.h
264-
265-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
266diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
267deleted file mode 100644
268index a87c57bc..00000000
269--- a/src/dht/Makefile.am
270+++ /dev/null
271@@ -1,18 +0,0 @@
272-noinst_LTLIBRARIES = libsub_dht.la
273-
274-libsub_dht_la_SOURCES = \
275- dht_bucket.cc \
276- dht_bucket.h \
277- dht_hash_map.h \
278- dht_node.cc \
279- dht_node.h \
280- dht_router.cc \
281- dht_router.h \
282- dht_server.cc \
283- dht_server.h \
284- dht_tracker.cc \
285- dht_tracker.h \
286- dht_transaction.cc \
287- dht_transaction.h
288-
289-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
290diff --git a/src/download/Makefile.am b/src/download/Makefile.am
291deleted file mode 100644
292index 65ceaf97..00000000
293--- a/src/download/Makefile.am
294+++ /dev/null
295@@ -1,19 +0,0 @@
296-noinst_LTLIBRARIES = libsub_download.la
297-
298-libsub_download_la_SOURCES = \
299- available_list.cc \
300- available_list.h \
301- chunk_selector.cc \
302- chunk_selector.h \
303- chunk_statistics.cc \
304- chunk_statistics.h \
305- delegator.cc \
306- delegator.h \
307- download_constructor.cc \
308- download_constructor.h \
309- download_main.cc \
310- download_main.h \
311- download_wrapper.cc \
312- download_wrapper.h
313-
314-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
315diff --git a/src/net/Makefile.am b/src/net/Makefile.am
316deleted file mode 100644
317index e3a8c7e1..00000000
318--- a/src/net/Makefile.am
319+++ /dev/null
320@@ -1,30 +0,0 @@
321-noinst_LTLIBRARIES = libsub_net.la
322-
323-libsub_net_la_SOURCES = \
324- address_list.cc \
325- address_list.h \
326- data_buffer.h \
327- local_addr.cc \
328- local_addr.h \
329- listen.cc \
330- listen.h \
331- protocol_buffer.h \
332- socket_base.cc \
333- socket_base.h \
334- socket_datagram.cc \
335- socket_datagram.h \
336- socket_fd.cc \
337- socket_fd.h \
338- socket_listen.cc \
339- socket_listen.h \
340- socket_set.cc \
341- socket_set.h \
342- socket_stream.cc \
343- socket_stream.h \
344- throttle_internal.cc \
345- throttle_internal.h \
346- throttle_list.cc \
347- throttle_list.h \
348- throttle_node.h
349-
350-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
351diff --git a/src/protocol/Makefile.am b/src/protocol/Makefile.am
352deleted file mode 100644
353index 2e9aba7a..00000000
354--- a/src/protocol/Makefile.am
355+++ /dev/null
356@@ -1,28 +0,0 @@
357-noinst_LTLIBRARIES = libsub_protocol.la
358-
359-libsub_protocol_la_SOURCES = \
360- encryption_info.h \
361- extensions.cc \
362- extensions.h \
363- handshake.cc \
364- handshake.h \
365- handshake_encryption.cc \
366- handshake_encryption.h \
367- handshake_manager.cc \
368- handshake_manager.h \
369- initial_seed.cc \
370- initial_seed.h \
371- peer_chunks.h \
372- peer_connection_base.cc \
373- peer_connection_base.h \
374- peer_connection_leech.cc \
375- peer_connection_leech.h \
376- peer_connection_metadata.cc \
377- peer_connection_metadata.h \
378- peer_factory.cc \
379- peer_factory.h \
380- protocol_base.h \
381- request_list.cc \
382- request_list.h
383-
384-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
385diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am
386index 8cd26ce7..30157b95 100644
387--- a/src/torrent/Makefile.am
388+++ b/src/torrent/Makefile.am
389@@ -1,13 +1,89 @@
390-SUBDIRS = \
391- data \
392- download \
393- net \
394- peer \
395- utils
396+noinst_LTLIBRARIES = libtorrent_torrent.la
397
398-noinst_LTLIBRARIES = libsub_torrent.la
399-
400-libsub_torrent_la_SOURCES = \
401+libtorrent_torrent_la_SOURCES = \
402+ data/block.cc \
403+ data/block.h \
404+ data/block_failed.h \
405+ data/block_list.cc \
406+ data/block_list.h \
407+ data/block_transfer.h \
408+ data/chunk_utils.cc \
409+ data/chunk_utils.h \
410+ data/download_data.cc \
411+ data/download_data.h \
412+ data/file.cc \
413+ data/file.h \
414+ data/file_list.cc \
415+ data/file_list.h \
416+ data/file_list_iterator.cc \
417+ data/file_list_iterator.h \
418+ data/file_manager.cc \
419+ data/file_manager.h \
420+ data/file_utils.cc \
421+ data/file_utils.h \
422+ data/piece.h \
423+ data/transfer_list.cc \
424+ data/transfer_list.h \
425+\
426+ download/choke_group.cc \
427+ download/choke_group.h \
428+ download/choke_queue.cc \
429+ download/choke_queue.h \
430+ download/download_manager.cc \
431+ download/download_manager.h \
432+ download/group_entry.h \
433+ download/resource_manager.cc \
434+ download/resource_manager.h \
435+\
436+ net/address_info.cc \
437+ net/address_info.h \
438+ net/fd.cc \
439+ net/fd.h \
440+ net/socket_address.cc \
441+ net/socket_address.h \
442+ net/socket_address_key.cc \
443+ net/socket_address_key.h \
444+ net/socket_event.cc \
445+ net/socket_event.h \
446+ net/types.h \
447+\
448+ peer/choke_status.h \
449+ peer/client_info.cc \
450+ peer/client_info.h \
451+ peer/client_list.cc \
452+ peer/client_list.h \
453+ peer/connection_list.cc \
454+ peer/connection_list.h \
455+ peer/peer.cc \
456+ peer/peer.h \
457+ peer/peer_info.cc \
458+ peer/peer_info.h \
459+ peer/peer_list.cc \
460+ peer/peer_list.h \
461+\
462+ utils/directory_events.cc \
463+ utils/directory_events.h \
464+ utils/extents.h \
465+ utils/log.cc \
466+ utils/log.h \
467+ utils/log_buffer.cc \
468+ utils/log_buffer.h \
469+ utils/option_strings.cc \
470+ utils/option_strings.h \
471+ utils/random.cc \
472+ utils/random.h \
473+ utils/ranges.h \
474+ utils/resume.cc \
475+ utils/resume.h \
476+ utils/signal_bitfield.cc \
477+ utils/signal_bitfield.h \
478+ utils/thread_base.cc \
479+ utils/thread_base.h \
480+ utils/thread_interrupt.cc \
481+ utils/thread_interrupt.h \
482+ utils/uri_parser.cc \
483+ utils/uri_parser.h \
484+\
485 bitfield.cc \
486 bitfield.h \
487 chunk_manager.cc \
488@@ -61,8 +137,64 @@ libsub_torrent_la_SOURCES = \
489
490 AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
491
492-libtorrentincludedir = $(includedir)/torrent
493-libtorrentinclude_HEADERS = \
494+libtorrent_torrent_data_includedir = $(includedir)/torrent/data
495+libtorrent_torrent_data_include_HEADERS = \
496+ data/block.h \
497+ data/block_list.h \
498+ data/block_transfer.h \
499+ data/chunk_utils.h \
500+ data/download_data.h \
501+ data/file.h \
502+ data/file_list.h \
503+ data/file_list_iterator.h \
504+ data/file_manager.h \
505+ data/file_utils.h \
506+ data/piece.h \
507+ data/transfer_list.h
508+
509+libtorrent_torrent_download_includedir = $(includedir)/torrent/download
510+libtorrent_torrent_download_include_HEADERS = \
511+ download/choke_group.h \
512+ download/choke_queue.h \
513+ download/download_manager.h \
514+ download/group_entry.h \
515+ download/resource_manager.h
516+
517+libtorrent_torrent_net_includedir = $(includedir)/torrent/net
518+libtorrent_torrent_net_include_HEADERS = \
519+ net/address_info.h \
520+ net/fd.h \
521+ net/socket_address.h \
522+ net/socket_address_key.h \
523+ net/socket_event.h \
524+ net/types.h
525+
526+libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer
527+libtorrent_torrent_peer_include_HEADERS = \
528+ peer/choke_status.h \
529+ peer/client_info.h \
530+ peer/client_list.h \
531+ peer/connection_list.h \
532+ peer/peer.h \
533+ peer/peer_info.h \
534+ peer/peer_list.h
535+
536+libtorrent_torrent_utils_includedir = $(includedir)/torrent/utils
537+libtorrent_torrent_utils_include_HEADERS = \
538+ utils/directory_events.h \
539+ utils/extents.h \
540+ utils/log.h \
541+ utils/log_buffer.h \
542+ utils/option_strings.h \
543+ utils/ranges.h \
544+ utils/resume.h \
545+ utils/signal_bitfield.h \
546+ utils/thread_base.h \
547+ utils/thread_interrupt.h \
548+ utils/uri_parser.h
549+
550+libtorrent_torrent_includedir = $(includedir)/torrent
551+libtorrent_torrent_include_HEADERS = \
552 bitfield.h \
553 chunk_manager.h \
554 common.h \
555diff --git a/src/torrent/download/Makefile.am b/src/torrent/download/Makefile.am
556deleted file mode 100644
557index f92c7aa4..00000000
558--- a/src/torrent/download/Makefile.am
559+++ /dev/null
560@@ -1,22 +0,0 @@
561-noinst_LTLIBRARIES = libsub_torrentdownload.la
562-
563-libsub_torrentdownload_la_SOURCES = \
564- choke_group.cc \
565- choke_group.h \
566- choke_queue.cc \
567- choke_queue.h \
568- download_manager.cc \
569- download_manager.h \
570- group_entry.h \
571- resource_manager.cc \
572- resource_manager.h
573-
574-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
575-
576-libtorrentincludedir = $(includedir)/torrent/download
577-libtorrentinclude_HEADERS = \
578- choke_group.h \
579- choke_queue.h \
580- download_manager.h \
581- group_entry.h \
582- resource_manager.h
583diff --git a/src/torrent/net/Makefile.am b/src/torrent/net/Makefile.am
584deleted file mode 100644
585index 35dd4774..00000000
586--- a/src/torrent/net/Makefile.am
587+++ /dev/null
588@@ -1,25 +0,0 @@
589-noinst_LTLIBRARIES = libsub_torrentnet.la
590-
591-libsub_torrentnet_la_SOURCES = \
592- address_info.cc \
593- address_info.h \
594- fd.cc \
595- fd.h \
596- socket_address.cc \
597- socket_address.h \
598- socket_address_key.cc \
599- socket_address_key.h \
600- socket_event.cc \
601- socket_event.h \
602- types.h
603-
604-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
605-
606-libtorrentincludedir = $(includedir)/torrent/net
607-libtorrentinclude_HEADERS = \
608- address_info.h \
609- fd.h \
610- socket_address.h \
611- socket_address_key.h \
612- socket_event.h \
613- types.h
614diff --git a/src/torrent/peer/Makefile.am b/src/torrent/peer/Makefile.am
615deleted file mode 100644
616index 1324e88a..00000000
617--- a/src/torrent/peer/Makefile.am
618+++ /dev/null
619@@ -1,28 +0,0 @@
620-noinst_LTLIBRARIES = libsub_torrentpeer.la
621-
622-libsub_torrentpeer_la_SOURCES = \
623- choke_status.h \
624- client_info.cc \
625- client_info.h \
626- client_list.cc \
627- client_list.h \
628- connection_list.cc \
629- connection_list.h \
630- peer.cc \
631- peer.h \
632- peer_info.cc \
633- peer_info.h \
634- peer_list.cc \
635- peer_list.h
636-
637-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
638-
639-libtorrentincludedir = $(includedir)/torrent/peer
640-libtorrentinclude_HEADERS = \
641- choke_status.h \
642- client_info.h \
643- client_list.h \
644- connection_list.h \
645- peer.h \
646- peer_info.h \
647- peer_list.h
648diff --git a/src/torrent/utils/Makefile.am b/src/torrent/utils/Makefile.am
649deleted file mode 100644
650index a48786c6..00000000
651--- a/src/torrent/utils/Makefile.am
652+++ /dev/null
653@@ -1,41 +0,0 @@
654-noinst_LTLIBRARIES = libsub_torrentutils.la
655-
656-libsub_torrentutils_la_SOURCES = \
657- directory_events.cc \
658- directory_events.h \
659- extents.h \
660- log.cc \
661- log.h \
662- log_buffer.cc \
663- log_buffer.h \
664- option_strings.cc \
665- option_strings.h \
666- random.cc \
667- random.h \
668- ranges.h \
669- resume.cc \
670- resume.h \
671- signal_bitfield.cc \
672- signal_bitfield.h \
673- thread_base.cc \
674- thread_base.h \
675- thread_interrupt.cc \
676- thread_interrupt.h \
677- uri_parser.cc \
678- uri_parser.h
679-
680-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
681-
682-libtorrentincludedir = $(includedir)/torrent/utils
683-libtorrentinclude_HEADERS = \
684- directory_events.h \
685- extents.h \
686- log.h \
687- log_buffer.h \
688- option_strings.h \
689- ranges.h \
690- resume.h \
691- signal_bitfield.h \
692- thread_base.h \
693- thread_interrupt.h \
694- uri_parser.h
695diff --git a/src/tracker/Makefile.am b/src/tracker/Makefile.am
696deleted file mode 100644
697index 2f1ae5cf..00000000
698--- a/src/tracker/Makefile.am
699+++ /dev/null
700@@ -1,11 +0,0 @@
701-noinst_LTLIBRARIES = libsub_tracker.la
702-
703-libsub_tracker_la_SOURCES = \
704- tracker_dht.cc \
705- tracker_dht.h \
706- tracker_http.cc \
707- tracker_http.h \
708- tracker_udp.cc \
709- tracker_udp.h
710-
711-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
712diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
713deleted file mode 100644
714index 27ce359b..00000000
715--- a/src/utils/Makefile.am
716+++ /dev/null
717@@ -1,14 +0,0 @@
718-noinst_LTLIBRARIES = libsub_utils.la
719-
720-libsub_utils_la_SOURCES = \
721- diffie_hellman.cc \
722- diffie_hellman.h \
723- instrumentation.cc \
724- instrumentation.h \
725- rc4.h \
726- sha1.h \
727- sha_fast.cc \
728- sha_fast.h \
729- queue_buckets.h
730-
731-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
732diff --git a/test/Makefile.am b/test/Makefile.am
733index 23b260e4..8b0291bb 100644
734--- a/test/Makefile.am
735+++ b/test/Makefile.am
736@@ -1,25 +1,68 @@
737-SUBDIRS = torrent/net net
738-
739-TESTS = LibTorrentTest
740-AUTOMAKE_OPTIONS = subdir-objects
741+TESTS = \
742+ LibTorrent_Test_Torrent_Net \
743+ LibTorrent_Test_Net \
744+ LibTorrent_Test
745
746 check_PROGRAMS = $(TESTS)
747-LibTorrentTest_LDADD = \
748+
749+LibTorrent_Test_LDADD = \
750 ../src/libtorrent.la \
751- ../src/torrent/libsub_torrent.la \
752- ../src/torrent/data/libsub_torrentdata.la \
753- ../src/torrent/download/libsub_torrentdownload.la \
754- ../src/torrent/peer/libsub_torrentpeer.la \
755- ../src/data/libsub_data.la \
756- ../src/dht/libsub_dht.la \
757- ../src/net/libsub_net.la \
758- ../src/protocol/libsub_protocol.la \
759- ../src/download/libsub_download.la \
760- ../src/tracker/libsub_tracker.la \
761- ../src/utils/libsub_utils.la \
762- ../src/torrent/utils/libsub_torrentutils.la
763+ ../src/libtorrent_other.la \
764+ ../src/torrent/libtorrent_torrent.la
765+
766+LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD)
767+LibTorrent_Test_Torrent_Net_LDADD = $(LibTorrent_Test_LDADD)
768+
769+# LibTorrent_Test_SOURCES = \
770+# helpers/expect_fd.h \
771+# helpers/expect_utils.h \
772+# helpers/mock_compare.h \
773+# helpers/mock_function.cc \
774+# helpers/mock_function.h \
775+# helpers/network.h \
776+# helpers/progress_listener.cc \
777+# helpers/progress_listener.h \
778+# helpers/test_fixture.cc \
779+# helpers/test_fixture.h
780+
781+LibTorrent_Test_Torrent_Net_SOURCES = \
782+ main.cc \
783+ helpers/expect_fd.h \
784+ helpers/expect_utils.h \
785+ helpers/mock_compare.h \
786+ helpers/mock_function.cc \
787+ helpers/mock_function.h \
788+ helpers/network.h \
789+ helpers/progress_listener.cc \
790+ helpers/progress_listener.h \
791+ helpers/test_fixture.cc \
792+ helpers/test_fixture.h \
793+ \
794+ torrent/net/test_address_info.cc \
795+ torrent/net/test_address_info.h \
796+ torrent/net/test_fd.cc \
797+ torrent/net/test_fd.h \
798+ torrent/net/test_socket_address.cc \
799+ torrent/net/test_socket_address.h
800
801-LibTorrentTest_SOURCES = \
802+LibTorrent_Test_Net_SOURCES = \
803+ main.cc \
804+ helpers/expect_fd.h \
805+ helpers/expect_utils.h \
806+ helpers/mock_compare.h \
807+ helpers/mock_function.cc \
808+ helpers/mock_function.h \
809+ helpers/network.h \
810+ helpers/progress_listener.cc \
811+ helpers/progress_listener.h \
812+ helpers/test_fixture.cc \
813+ helpers/test_fixture.h \
814+ \
815+ net/test_socket_listen.cc \
816+ net/test_socket_listen.h
817+
818+LibTorrent_Test_SOURCES = \
819+ main.cc \
820 helpers/expect_fd.h \
821 helpers/expect_utils.h \
822 helpers/mock_compare.h \
823@@ -87,12 +130,15 @@ LibTorrentTest_SOURCES = \
824 torrent/tracker_list_features_test.h \
825 torrent/tracker_timeout_test.cc \
826 torrent/tracker_timeout_test.h \
827- tracker/tracker_http_test.cc \
828- tracker/tracker_http_test.h \
829 \
830- main.cc
831+ tracker/tracker_http_test.cc \
832+ tracker/tracker_http_test.h
833
834-LibTorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
835-LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
836+LibTorrent_Test_Torrent_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
837+LibTorrent_Test_Torrent_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
838+LibTorrent_Test_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
839+LibTorrent_Test_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
840+LibTorrent_Test_CXXFLAGS = $(CPPUNIT_CFLAGS)
841+LibTorrent_Test_LDFLAGS = $(CPPUNIT_LIBS) -ldl
842
843 AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch
new file mode 100644
index 0000000000..4c7a2038fb
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch
@@ -0,0 +1,2710 @@
1From 9cdb950c0db2bad1a4d85b48f06419e2920aa114 Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Fri, 20 Dec 2019 00:37:38 +0900
4Subject: [PATCH] Refactor make process. (#207)
5
6---
7 configure.ac | 3 +-
8 src/Makefile.am | 3 +-
9 src/manager.h | 36 ---
10 src/thread_disk.h | 51 +---
11 src/torrent/utils/thread_base.cc | 36 ---
12 src/torrent/utils/thread_base.h | 48 +---
13 test/Makefile.am | 140 +++++------
14 ...{chunk_list_test.cc => test_chunk_list.cc} | 16 +-
15 .../{chunk_list_test.h => test_chunk_list.h} | 13 +-
16 ...queue_test.cc => test_hash_check_queue.cc} | 33 ++-
17 ...k_queue_test.h => test_hash_check_queue.h} | 22 +-
18 ...{hash_queue_test.cc => test_hash_queue.cc} | 66 +++---
19 .../{hash_queue_test.h => test_hash_queue.h} | 11 +-
20 test/helpers/progress_listener.cc | 4 +-
21 test/helpers/test_fixture.h | 28 +--
22 test/helpers/test_thread.cc | 71 ++++++
23 test/helpers/test_thread.h | 59 +++++
24 test/helpers/test_utils.h | 16 ++
25 test/helpers/utils.h | 120 +++++-----
26 test/main.cc | 4 +-
27 test/torrent/{http_test.cc => test_http.cc} | 17 +-
28 test/torrent/{http_test.h => test_http.h} | 11 +-
29 test/torrent/utils/option_strings_test.h | 17 --
30 test/torrent/utils/signal_bitfield_test.h | 23 --
31 test/torrent/utils/test_extents.cc | 63 ++---
32 test/torrent/utils/test_extents.h | 9 +-
33 .../utils/{log_test.cc => test_log.cc} | 26 +-
34 test/torrent/utils/{log_test.h => test_log.h} | 8 +-
35 test/torrent/utils/test_log_buffer.cc | 11 +-
36 test/torrent/utils/test_log_buffer.h | 5 -
37 ...strings_test.cc => test_option_strings.cc} | 29 +--
38 test/torrent/utils/test_option_strings.h | 10 +
39 test/torrent/utils/test_queue_buckets.cc | 12 +-
40 test/torrent/utils/test_queue_buckets.h | 11 +-
41 ...tfield_test.cc => test_signal_bitfield.cc} | 31 ++-
42 test/torrent/utils/test_signal_bitfield.h | 22 ++
43 test/torrent/utils/test_thread_base.cc | 169 +++++++++++++
44 test/torrent/utils/test_thread_base.h | 25 ++
45 test/torrent/utils/test_uri_parser.cc | 31 +--
46 test/torrent/utils/test_uri_parser.h | 11 +-
47 test/torrent/utils/thread_base_test.cc | 224 ------------------
48 test/torrent/utils/thread_base_test.h | 86 -------
49 test/tracker/test_tracker_http.cc | 11 +
50 test/tracker/test_tracker_http.h | 12 +
51 test/tracker/tracker_http_test.cc | 17 --
52 test/tracker/tracker_http_test.h | 18 --
53 46 files changed, 735 insertions(+), 954 deletions(-)
54 rename test/data/{chunk_list_test.cc => test_chunk_list.cc} (93%)
55 rename test/data/{chunk_list_test.h => test_chunk_list.h} (88%)
56 rename test/data/{hash_check_queue_test.cc => test_hash_check_queue.cc} (92%)
57 rename test/data/{hash_check_queue_test.h => test_hash_check_queue.h} (63%)
58 rename test/data/{hash_queue_test.cc => test_hash_queue.cc} (82%)
59 rename test/data/{hash_queue_test.h => test_hash_queue.h} (58%)
60 create mode 100755 test/helpers/test_thread.cc
61 create mode 100755 test/helpers/test_thread.h
62 create mode 100644 test/helpers/test_utils.h
63 rename test/torrent/{http_test.cc => test_http.cc} (94%)
64 rename test/torrent/{http_test.h => test_http.h} (63%)
65 delete mode 100644 test/torrent/utils/option_strings_test.h
66 delete mode 100644 test/torrent/utils/signal_bitfield_test.h
67 rename test/torrent/utils/{log_test.cc => test_log.cc} (92%)
68 rename test/torrent/utils/{log_test.h => test_log.h} (71%)
69 rename test/torrent/utils/{option_strings_test.cc => test_option_strings.cc} (65%)
70 create mode 100644 test/torrent/utils/test_option_strings.h
71 rename test/torrent/utils/{signal_bitfield_test.cc => test_signal_bitfield.cc} (85%)
72 create mode 100644 test/torrent/utils/test_signal_bitfield.h
73 create mode 100644 test/torrent/utils/test_thread_base.cc
74 create mode 100644 test/torrent/utils/test_thread_base.h
75 delete mode 100644 test/torrent/utils/thread_base_test.cc
76 delete mode 100644 test/torrent/utils/thread_base_test.h
77 create mode 100644 test/tracker/test_tracker_http.cc
78 create mode 100644 test/tracker/test_tracker_http.h
79 delete mode 100644 test/tracker/tracker_http_test.cc
80 delete mode 100644 test/tracker/tracker_http_test.h
81
82diff --git a/configure.ac b/configure.ac
83index e83710cc..88a46edd 100644
84--- a/configure.ac
85+++ b/configure.ac
86@@ -21,6 +21,7 @@ AM_INIT_AUTOMAKE([serial-tests subdir-objects])
87 AC_CONFIG_HEADERS(config.h)
88
89 AC_PROG_CXX
90+AC_SYS_LARGEFILE
91
92 AC_C_BIGENDIAN(
93 AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian),
94@@ -37,8 +38,6 @@ RAK_DISABLE_BACKTRACE
95
96 RAK_CHECK_CXX11
97
98-AC_SYS_LARGEFILE
99-
100 TORRENT_ENABLE_ALIGNED
101 TORRENT_ENABLE_INTERRUPT_SOCKET
102
103diff --git a/src/Makefile.am b/src/Makefile.am
104index e96bd74b..95e6a7ae 100644
105--- a/src/Makefile.am
106+++ b/src/Makefile.am
107@@ -1,7 +1,8 @@
108 SUBDIRS = torrent
109
110 lib_LTLIBRARIES = libtorrent.la
111-noinst_LTLIBRARIES = libtorrent_other.la
112+noinst_LTLIBRARIES = \
113+ libtorrent_other.la
114
115 libtorrent_la_LDFLAGS = -version-info $(LIBTORRENT_INTERFACE_VERSION_INFO)
116 libtorrent_la_LIBADD = \
117diff --git a/src/manager.h b/src/manager.h
118index 1db81e9b..1ada9567 100644
119--- a/src/manager.h
120+++ b/src/manager.h
121@@ -1,39 +1,3 @@
122-// libTorrent - BitTorrent library
123-// Copyright (C) 2005-2011, Jari Sundell
124-//
125-// This program is free software; you can redistribute it and/or modify
126-// it under the terms of the GNU General Public License as published by
127-// the Free Software Foundation; either version 2 of the License, or
128-// (at your option) any later version.
129-//
130-// This program is distributed in the hope that it will be useful,
131-// but WITHOUT ANY WARRANTY; without even the implied warranty of
132-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
133-// GNU General Public License for more details.
134-//
135-// You should have received a copy of the GNU General Public License
136-// along with this program; if not, write to the Free Software
137-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
138-//
139-// In addition, as a special exception, the copyright holders give
140-// permission to link the code of portions of this program with the
141-// OpenSSL library under certain conditions as described in each
142-// individual source file, and distribute linked combinations
143-// including the two.
144-//
145-// You must obey the GNU General Public License in all respects for
146-// all of the code used other than OpenSSL. If you modify file(s)
147-// with this exception, you may extend this exception to your version
148-// of the file(s), but you are not obligated to do so. If you do not
149-// wish to do so, delete this exception statement from your version.
150-// If you delete this exception statement from all source files in the
151-// program, then also delete it here.
152-//
153-// Contact: Jari Sundell <jaris@ifi.uio.no>
154-//
155-// Skomakerveien 33
156-// 3185 Skoppum, NORWAY
157-
158 #ifndef LIBTORRENT_MANAGER_H
159 #define LIBTORRENT_MANAGER_H
160
161diff --git a/src/thread_disk.h b/src/thread_disk.h
162index fa1fcb7e..7b378915 100644
163--- a/src/thread_disk.h
164+++ b/src/thread_disk.h
165@@ -1,39 +1,3 @@
166-// libTorrent - BitTorrent library
167-// Copyright (C) 2005-2011, Jari Sundell
168-//
169-// This program is free software; you can redistribute it and/or modify
170-// it under the terms of the GNU General Public License as published by
171-// the Free Software Foundation; either version 2 of the License, or
172-// (at your option) any later version.
173-//
174-// This program is distributed in the hope that it will be useful,
175-// but WITHOUT ANY WARRANTY; without even the implied warranty of
176-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
177-// GNU General Public License for more details.
178-//
179-// You should have received a copy of the GNU General Public License
180-// along with this program; if not, write to the Free Software
181-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
182-//
183-// In addition, as a special exception, the copyright holders give
184-// permission to link the code of portions of this program with the
185-// OpenSSL library under certain conditions as described in each
186-// individual source file, and distribute linked combinations
187-// including the two.
188-//
189-// You must obey the GNU General Public License in all respects for
190-// all of the code used other than OpenSSL. If you modify file(s)
191-// with this exception, you may extend this exception to your version
192-// of the file(s), but you are not obligated to do so. If you do not
193-// wish to do so, delete this exception statement from your version.
194-// If you delete this exception statement from all source files in the
195-// program, then also delete it here.
196-//
197-// Contact: Jari Sundell <jaris@ifi.uio.no>
198-//
199-// Skomakerveien 33
200-// 3185 Skoppum, NORWAY
201-
202 #ifndef LIBTORRENT_THREAD_DISK_H
203 #define LIBTORRENT_THREAD_DISK_H
204
205@@ -42,19 +6,18 @@
206
207 namespace torrent {
208
209-class thread_disk : public thread_base {
210+class LIBTORRENT_EXPORT thread_disk : public thread_base {
211 public:
212- const char* name() const { return "rtorrent disk"; }
213-
214- virtual void init_thread();
215+ const char* name() const { return "rtorrent disk"; }
216+ HashCheckQueue* hash_queue() { return &m_hash_queue; }
217
218- HashCheckQueue* hash_queue() { return &m_hash_queue; }
219+ virtual void init_thread();
220
221 protected:
222- virtual void call_events();
223- virtual int64_t next_timeout_usec();
224+ virtual void call_events();
225+ virtual int64_t next_timeout_usec();
226
227- HashCheckQueue m_hash_queue;
228+ HashCheckQueue m_hash_queue;
229 };
230
231 }
232diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc
233index 778e4c38..99d6355d 100644
234--- a/src/torrent/utils/thread_base.cc
235+++ b/src/torrent/utils/thread_base.cc
236@@ -1,39 +1,3 @@
237-// libTorrent - BitTorrent library
238-// Copyright (C) 2005-2011, Jari Sundell
239-//
240-// This program is free software; you can redistribute it and/or modify
241-// it under the terms of the GNU General Public License as published by
242-// the Free Software Foundation; either version 2 of the License, or
243-// (at your option) any later version.
244-//
245-// This program is distributed in the hope that it will be useful,
246-// but WITHOUT ANY WARRANTY; without even the implied warranty of
247-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
248-// GNU General Public License for more details.
249-//
250-// You should have received a copy of the GNU General Public License
251-// along with this program; if not, write to the Free Software
252-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
253-//
254-// In addition, as a special exception, the copyright holders give
255-// permission to link the code of portions of this program with the
256-// OpenSSL library under certain conditions as described in each
257-// individual source file, and distribute linked combinations
258-// including the two.
259-//
260-// You must obey the GNU General Public License in all respects for
261-// all of the code used other than OpenSSL. If you modify file(s)
262-// with this exception, you may extend this exception to your version
263-// of the file(s), but you are not obligated to do so. If you do not
264-// wish to do so, delete this exception statement from your version.
265-// If you delete this exception statement from all source files in the
266-// program, then also delete it here.
267-//
268-// Contact: Jari Sundell <jaris@ifi.uio.no>
269-//
270-// Skomakerveien 33
271-// 3185 Skoppum, NORWAY
272-
273 #include "config.h"
274
275 #include <cstring>
276diff --git a/src/torrent/utils/thread_base.h b/src/torrent/utils/thread_base.h
277index b92a98ba..bead9659 100644
278--- a/src/torrent/utils/thread_base.h
279+++ b/src/torrent/utils/thread_base.h
280@@ -1,48 +1,12 @@
281-// libTorrent - BitTorrent library
282-// Copyright (C) 2005-2011, Jari Sundell
283-//
284-// This program is free software; you can redistribute it and/or modify
285-// it under the terms of the GNU General Public License as published by
286-// the Free Software Foundation; either version 2 of the License, or
287-// (at your option) any later version.
288-//
289-// This program is distributed in the hope that it will be useful,
290-// but WITHOUT ANY WARRANTY; without even the implied warranty of
291-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
292-// GNU General Public License for more details.
293-//
294-// You should have received a copy of the GNU General Public License
295-// along with this program; if not, write to the Free Software
296-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
297-//
298-// In addition, as a special exception, the copyright holders give
299-// permission to link the code of portions of this program with the
300-// OpenSSL library under certain conditions as described in each
301-// individual source file, and distribute linked combinations
302-// including the two.
303-//
304-// You must obey the GNU General Public License in all respects for
305-// all of the code used other than OpenSSL. If you modify file(s)
306-// with this exception, you may extend this exception to your version
307-// of the file(s), but you are not obligated to do so. If you do not
308-// wish to do so, delete this exception statement from your version.
309-// If you delete this exception statement from all source files in the
310-// program, then also delete it here.
311-//
312-// Contact: Jari Sundell <jaris@ifi.uio.no>
313-//
314-// Skomakerveien 33
315-// 3185 Skoppum, NORWAY
316-
317 #ifndef LIBTORRENT_UTILS_THREAD_BASE_H
318 #define LIBTORRENT_UTILS_THREAD_BASE_H
319
320-#include <functional>
321-#include <pthread.h>
322-#include <sys/types.h>
323+#import <functional>
324+#import <pthread.h>
325+#import <sys/types.h>
326
327-#include <torrent/common.h>
328-#include <torrent/utils/signal_bitfield.h>
329+#import <torrent/common.h>
330+#import <torrent/utils/signal_bitfield.h>
331
332 namespace torrent {
333
334@@ -54,7 +18,7 @@ public:
335 typedef void* (*pthread_func)(void*);
336 typedef std::function<void ()> slot_void;
337 typedef std::function<uint64_t ()> slot_timer;
338- typedef class signal_bitfield signal_type;
339+ typedef class signal_bitfield signal_type;
340
341 enum state_type {
342 STATE_UNKNOWN,
343diff --git a/test/Makefile.am b/test/Makefile.am
344index 8b0291bb..cb00dce3 100644
345--- a/test/Makefile.am
346+++ b/test/Makefile.am
347@@ -1,6 +1,10 @@
348 TESTS = \
349 LibTorrent_Test_Torrent_Net \
350+ LibTorrent_Test_Torrent_Utils \
351+ LibTorrent_Test_Torrent \
352+ LibTorrent_Test_Data \
353 LibTorrent_Test_Net \
354+ LibTorrent_Test_Tracker \
355 LibTorrent_Test
356
357 check_PROGRAMS = $(TESTS)
358@@ -10,22 +14,14 @@ LibTorrent_Test_LDADD = \
359 ../src/libtorrent_other.la \
360 ../src/torrent/libtorrent_torrent.la
361
362-LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD)
363 LibTorrent_Test_Torrent_Net_LDADD = $(LibTorrent_Test_LDADD)
364+LibTorrent_Test_Torrent_Utils_LDADD = $(LibTorrent_Test_LDADD)
365+LibTorrent_Test_Torrent_LDADD = $(LibTorrent_Test_LDADD)
366+LibTorrent_Test_Data_LDADD = $(LibTorrent_Test_LDADD)
367+LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD)
368+LibTorrent_Test_Tracker_LDADD = $(LibTorrent_Test_LDADD)
369
370-# LibTorrent_Test_SOURCES = \
371-# helpers/expect_fd.h \
372-# helpers/expect_utils.h \
373-# helpers/mock_compare.h \
374-# helpers/mock_function.cc \
375-# helpers/mock_function.h \
376-# helpers/network.h \
377-# helpers/progress_listener.cc \
378-# helpers/progress_listener.h \
379-# helpers/test_fixture.cc \
380-# helpers/test_fixture.h
381-
382-LibTorrent_Test_Torrent_Net_SOURCES = \
383+LibTorrent_Test_Common = \
384 main.cc \
385 helpers/expect_fd.h \
386 helpers/expect_utils.h \
387@@ -37,7 +33,10 @@ LibTorrent_Test_Torrent_Net_SOURCES = \
388 helpers/progress_listener.h \
389 helpers/test_fixture.cc \
390 helpers/test_fixture.h \
391- \
392+ helpers/test_thread.cc \
393+ helpers/test_thread.h
394+
395+LibTorrent_Test_Torrent_Net_SOURCES = $(LibTorrent_Test_Common) \
396 torrent/net/test_address_info.cc \
397 torrent/net/test_address_info.h \
398 torrent/net/test_fd.cc \
399@@ -45,71 +44,28 @@ LibTorrent_Test_Torrent_Net_SOURCES = \
400 torrent/net/test_socket_address.cc \
401 torrent/net/test_socket_address.h
402
403-LibTorrent_Test_Net_SOURCES = \
404- main.cc \
405- helpers/expect_fd.h \
406- helpers/expect_utils.h \
407- helpers/mock_compare.h \
408- helpers/mock_function.cc \
409- helpers/mock_function.h \
410- helpers/network.h \
411- helpers/progress_listener.cc \
412- helpers/progress_listener.h \
413- helpers/test_fixture.cc \
414- helpers/test_fixture.h \
415- \
416- net/test_socket_listen.cc \
417- net/test_socket_listen.h
418-
419-LibTorrent_Test_SOURCES = \
420- main.cc \
421- helpers/expect_fd.h \
422- helpers/expect_utils.h \
423- helpers/mock_compare.h \
424- helpers/mock_function.cc \
425- helpers/mock_function.h \
426- helpers/network.h \
427- helpers/progress_listener.cc \
428- helpers/progress_listener.h \
429- helpers/test_fixture.cc \
430- helpers/test_fixture.h \
431- \
432- ../src/thread_disk.cc \
433- ../src/thread_disk.h \
434- \
435- rak/allocators_test.cc \
436- rak/allocators_test.h \
437- rak/ranges_test.cc \
438- rak/ranges_test.h \
439- data/chunk_list_test.cc \
440- data/chunk_list_test.h \
441- data/hash_check_queue_test.cc \
442- data/hash_check_queue_test.h \
443- data/hash_queue_test.cc \
444- data/hash_queue_test.h \
445- \
446- protocol/test_request_list.cc \
447- protocol/test_request_list.h \
448- \
449- torrent/utils/log_test.cc \
450- torrent/utils/log_test.h \
451- torrent/utils/option_strings_test.cc \
452- torrent/utils/option_strings_test.h \
453+LibTorrent_Test_Torrent_Utils_SOURCES = $(LibTorrent_Test_Common) \
454 torrent/utils/test_extents.cc \
455 torrent/utils/test_extents.h \
456+ torrent/utils/test_log.cc \
457+ torrent/utils/test_log.h \
458 torrent/utils/test_log_buffer.cc \
459 torrent/utils/test_log_buffer.h \
460+ torrent/utils/test_option_strings.cc \
461+ torrent/utils/test_option_strings.h \
462 torrent/utils/test_queue_buckets.cc \
463 torrent/utils/test_queue_buckets.h \
464+ torrent/utils/test_signal_bitfield.cc \
465+ torrent/utils/test_signal_bitfield.h \
466+ torrent/utils/test_thread_base.cc \
467+ torrent/utils/test_thread_base.h \
468 torrent/utils/test_uri_parser.cc \
469- torrent/utils/test_uri_parser.h \
470- torrent/utils/signal_bitfield_test.cc \
471- torrent/utils/signal_bitfield_test.h \
472- torrent/utils/thread_base_test.cc \
473- torrent/utils/thread_base_test.h \
474+ torrent/utils/test_uri_parser.h
475+
476+LibTorrent_Test_Torrent_SOURCES = $(LibTorrent_Test_Common) \
477+ torrent/test_http.cc \
478+ torrent/test_http.h \
479 \
480- torrent/http_test.cc \
481- torrent/http_test.h \
482 torrent/object_test.cc \
483 torrent/object_test.h \
484 torrent/object_test_utils.cc \
485@@ -129,15 +85,49 @@ LibTorrent_Test_SOURCES = \
486 torrent/tracker_list_features_test.cc \
487 torrent/tracker_list_features_test.h \
488 torrent/tracker_timeout_test.cc \
489- torrent/tracker_timeout_test.h \
490+ torrent/tracker_timeout_test.h
491+
492+LibTorrent_Test_Data_SOURCES = $(LibTorrent_Test_Common) \
493+ data/test_chunk_list.cc \
494+ data/test_chunk_list.h \
495+ data/test_hash_check_queue.cc \
496+ data/test_hash_check_queue.h \
497+ data/test_hash_queue.cc \
498+ data/test_hash_queue.h
499+
500+LibTorrent_Test_Net_SOURCES = $(LibTorrent_Test_Common) \
501+ net/test_socket_listen.cc \
502+ net/test_socket_listen.h
503+
504+LibTorrent_Test_Tracker_SOURCES = $(LibTorrent_Test_Common) \
505+ tracker/test_tracker_http.cc \
506+ tracker/test_tracker_http.h
507+
508+LibTorrent_Test_SOURCES = $(LibTorrent_Test_Common) \
509+ \
510+ ../src/thread_disk.cc \
511+ ../src/thread_disk.h \
512 \
513- tracker/tracker_http_test.cc \
514- tracker/tracker_http_test.h
515+ rak/allocators_test.cc \
516+ rak/allocators_test.h \
517+ rak/ranges_test.cc \
518+ rak/ranges_test.h \
519+ \
520+ protocol/test_request_list.cc \
521+ protocol/test_request_list.h
522
523 LibTorrent_Test_Torrent_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
524 LibTorrent_Test_Torrent_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
525+LibTorrent_Test_Torrent_Utils_CXXFLAGS = $(CPPUNIT_CFLAGS)
526+LibTorrent_Test_Torrent_Utils_LDFLAGS = $(CPPUNIT_LIBS) -ldl
527+LibTorrent_Test_Torrent_CXXFLAGS = $(CPPUNIT_CFLAGS)
528+LibTorrent_Test_Torrent_LDFLAGS = $(CPPUNIT_LIBS) -ldl
529+LibTorrent_Test_Data_CXXFLAGS = $(CPPUNIT_CFLAGS)
530+LibTorrent_Test_Data_LDFLAGS = $(CPPUNIT_LIBS) -ldl
531 LibTorrent_Test_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
532 LibTorrent_Test_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
533+LibTorrent_Test_Tracker_CXXFLAGS = $(CPPUNIT_CFLAGS)
534+LibTorrent_Test_Tracker_LDFLAGS = $(CPPUNIT_LIBS) -ldl
535 LibTorrent_Test_CXXFLAGS = $(CPPUNIT_CFLAGS)
536 LibTorrent_Test_LDFLAGS = $(CPPUNIT_LIBS) -ldl
537
538diff --git a/test/data/chunk_list_test.cc b/test/data/test_chunk_list.cc
539similarity index 93%
540rename from test/data/chunk_list_test.cc
541rename to test/data/test_chunk_list.cc
542index 28647db2..18de597e 100644
543--- a/test/data/chunk_list_test.cc
544+++ b/test/data/test_chunk_list.cc
545@@ -1,11 +1,11 @@
546-#include "config.h"
547+#import "config.h"
548
549-#include "chunk_list_test.h"
550+#import "test_chunk_list.h"
551
552-#include "torrent/chunk_manager.h"
553-#include "torrent/exceptions.h"
554+#import "torrent/chunk_manager.h"
555+#import "torrent/exceptions.h"
556
557-CPPUNIT_TEST_SUITE_REGISTRATION(ChunkListTest);
558+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_chunk_list, "data");
559
560 torrent::Chunk*
561 func_create_chunk(uint32_t index, int prot_flags) {
562@@ -36,7 +36,7 @@ func_storage_error(torrent::ChunkList* chunk_list, const std::string& message) {
563 }
564
565 void
566-ChunkListTest::test_basic() {
567+test_chunk_list::test_basic() {
568 torrent::ChunkManager chunk_manager;
569 torrent::ChunkList chunk_list;
570
571@@ -55,7 +55,7 @@ ChunkListTest::test_basic() {
572 }
573
574 void
575-ChunkListTest::test_get_release() {
576+test_chunk_list::test_get_release() {
577 SETUP_CHUNK_LIST();
578
579 CPPUNIT_ASSERT(!(*chunk_list)[0].is_valid());
580@@ -112,7 +112,7 @@ ChunkListTest::test_get_release() {
581
582 // Make sure we can't go into writable when blocking, etc.
583 void
584-ChunkListTest::test_blocking() {
585+test_chunk_list::test_blocking() {
586 SETUP_CHUNK_LIST();
587
588 torrent::ChunkHandle handle_0_ro = chunk_list->get(0, torrent::ChunkList::get_blocking);
589diff --git a/test/data/chunk_list_test.h b/test/data/test_chunk_list.h
590similarity index 88%
591rename from test/data/chunk_list_test.h
592rename to test/data/test_chunk_list.h
593index 3979982f..85d1f77b 100644
594--- a/test/data/chunk_list_test.h
595+++ b/test/data/test_chunk_list.h
596@@ -1,23 +1,22 @@
597-#include <cppunit/extensions/HelperMacros.h>
598+#import "helpers/test_fixture.h"
599
600-#include "data/chunk_list.h"
601+class test_chunk_list : public test_fixture {
602+ CPPUNIT_TEST_SUITE(test_chunk_list);
603
604-class ChunkListTest : public CppUnit::TestFixture {
605- CPPUNIT_TEST_SUITE(ChunkListTest);
606 CPPUNIT_TEST(test_basic);
607 CPPUNIT_TEST(test_get_release);
608 CPPUNIT_TEST(test_blocking);
609+
610 CPPUNIT_TEST_SUITE_END();
611
612 public:
613- void setUp() {}
614- void tearDown() {}
615-
616 void test_basic();
617 void test_get_release();
618 void test_blocking();
619 };
620
621+#include "data/chunk_list.h"
622+
623 torrent::Chunk* func_create_chunk(uint32_t index, int prot_flags);
624 uint64_t func_free_diskspace(torrent::ChunkList* chunk_list);
625 void func_storage_error(torrent::ChunkList* chunk_list, const std::string& message);
626diff --git a/test/data/hash_check_queue_test.cc b/test/data/test_hash_check_queue.cc
627similarity index 92%
628rename from test/data/hash_check_queue_test.cc
629rename to test/data/test_hash_check_queue.cc
630index 4b15245e..65931273 100644
631--- a/test/data/hash_check_queue_test.cc
632+++ b/test/data/test_hash_check_queue.cc
633@@ -1,20 +1,23 @@
634 #include "config.h"
635
636+#include "test_hash_check_queue.h"
637+
638+#include "helpers/test_thread.h"
639+#include "helpers/test_utils.h"
640+
641 #include <functional>
642 #include <signal.h>
643
644-#include "data/hash_queue_node.h"
645+#include "data/chunk_handle.h"
646 #include "utils/sha1.h"
647 #include "torrent/chunk_manager.h"
648 #include "torrent/exceptions.h"
649 #include "torrent/poll_select.h"
650-#include "torrent/utils/thread_base_test.h"
651 #include "thread_disk.h"
652
653-#include "chunk_list_test.h"
654-#include "hash_check_queue_test.h"
655+#include "test_chunk_list.h"
656
657-CPPUNIT_TEST_SUITE_REGISTRATION(HashCheckQueueTest);
658+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_hash_check_queue, "data");
659
660 pthread_mutex_t done_chunks_lock = PTHREAD_MUTEX_INITIALIZER;
661
662@@ -68,22 +71,16 @@ static torrent::Poll* create_select_poll() { return torrent::PollSelect::create(
663 static void do_nothing() {}
664
665 void
666-HashCheckQueueTest::setUp() {
667+test_hash_check_queue::setUp() {
668+ test_fixture::setUp();
669+
670 torrent::Poll::slot_create_poll() = std::bind(&create_select_poll);
671
672 signal(SIGUSR1, (sig_t)&do_nothing);
673 }
674
675 void
676-HashCheckQueueTest::tearDown() {
677-}
678-
679-void
680-HashCheckQueueTest::test_basic() {
681-}
682-
683-void
684-HashCheckQueueTest::test_single() {
685+test_hash_check_queue::test_single() {
686 SETUP_CHUNK_LIST();
687 torrent::HashCheckQueue hash_queue;
688
689@@ -110,7 +107,7 @@ HashCheckQueueTest::test_single() {
690 }
691
692 void
693-HashCheckQueueTest::test_multiple() {
694+test_hash_check_queue::test_multiple() {
695 SETUP_CHUNK_LIST();
696 torrent::HashCheckQueue hash_queue;
697
698@@ -143,7 +140,7 @@ HashCheckQueueTest::test_multiple() {
699 }
700
701 void
702-HashCheckQueueTest::test_erase() {
703+test_hash_check_queue::test_erase() {
704 // SETUP_CHUNK_LIST();
705 // torrent::HashCheckQueue hash_queue;
706
707@@ -176,7 +173,7 @@ HashCheckQueueTest::test_erase() {
708 }
709
710 void
711-HashCheckQueueTest::test_thread() {
712+test_hash_check_queue::test_thread() {
713 SETUP_CHUNK_LIST();
714 SETUP_THREAD();
715 thread_disk->start_thread();
716diff --git a/test/data/hash_check_queue_test.h b/test/data/test_hash_check_queue.h
717similarity index 63%
718rename from test/data/hash_check_queue_test.h
719rename to test/data/test_hash_check_queue.h
720index 5398a50d..d2d271bb 100644
721--- a/test/data/hash_check_queue_test.h
722+++ b/test/data/test_hash_check_queue.h
723@@ -1,26 +1,19 @@
724-#include <map>
725-#include <vector>
726-#include <cppunit/extensions/HelperMacros.h>
727+#import "helpers/test_fixture.h"
728
729-#include "data/hash_check_queue.h"
730-#include "torrent/hash_string.h"
731+class test_hash_check_queue : public test_fixture {
732+ CPPUNIT_TEST_SUITE(test_hash_check_queue);
733
734-
735-class HashCheckQueueTest : public CppUnit::TestFixture {
736- CPPUNIT_TEST_SUITE(HashCheckQueueTest);
737- CPPUNIT_TEST(test_basic);
738 CPPUNIT_TEST(test_single);
739 CPPUNIT_TEST(test_multiple);
740 CPPUNIT_TEST(test_erase);
741
742 CPPUNIT_TEST(test_thread);
743+
744 CPPUNIT_TEST_SUITE_END();
745
746 public:
747 void setUp();
748- void tearDown();
749
750- void test_basic();
751 void test_single();
752 void test_multiple();
753 void test_erase();
754@@ -28,6 +21,13 @@ public:
755 void test_thread();
756 };
757
758+#import <map>
759+#import <vector>
760+
761+#import "data/hash_queue_node.h"
762+#import "data/hash_check_queue.h"
763+#import "torrent/hash_string.h"
764+
765 typedef std::map<int, torrent::HashString> done_chunks_type;
766 typedef std::vector<torrent::ChunkHandle> handle_list;
767
768diff --git a/test/data/hash_queue_test.cc b/test/data/test_hash_queue.cc
769similarity index 82%
770rename from test/data/hash_queue_test.cc
771rename to test/data/test_hash_queue.cc
772index d7ce3ba8..d9a88c8d 100644
773--- a/test/data/hash_queue_test.cc
774+++ b/test/data/test_hash_queue.cc
775@@ -1,22 +1,26 @@
776-#include "config.h"
777+#import "config.h"
778
779-#include <functional>
780-#include <signal.h>
781+#import "test_hash_queue.h"
782
783-#include "data/hash_queue_node.h"
784-#include "torrent/chunk_manager.h"
785-#include "torrent/exceptions.h"
786-#include "torrent/hash_string.h"
787-#include "torrent/poll_select.h"
788-#include "torrent/utils/thread_base_test.h"
789-#include "globals.h"
790-#include "thread_disk.h"
791+#import "helpers/test_thread.h"
792+#import "helpers/test_utils.h"
793
794-#include "chunk_list_test.h"
795-#include "hash_queue_test.h"
796-#include "hash_check_queue_test.h"
797+#import <functional>
798+#import <signal.h>
799
800-CPPUNIT_TEST_SUITE_REGISTRATION(HashQueueTest);
801+#import "data/hash_queue.h"
802+#import "data/hash_queue_node.h"
803+#import "torrent/chunk_manager.h"
804+#import "torrent/exceptions.h"
805+#import "torrent/hash_string.h"
806+#import "torrent/poll_select.h"
807+#import "globals.h"
808+#import "thread_disk.h"
809+
810+#import "test_chunk_list.h"
811+#import "test_hash_check_queue.h"
812+
813+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_hash_queue, "data");
814
815 typedef std::map<int, torrent::HashString> done_chunks_type;
816
817@@ -39,7 +43,9 @@ static torrent::Poll* create_select_poll() { return torrent::PollSelect::create(
818 static void do_nothing() {}
819
820 void
821-HashQueueTest::setUp() {
822+test_hash_queue::setUp() {
823+ test_fixture::setUp();
824+
825 CPPUNIT_ASSERT(torrent::taskScheduler.empty());
826
827 torrent::Poll::slot_create_poll() = std::bind(&create_select_poll);
828@@ -47,25 +53,9 @@ HashQueueTest::setUp() {
829 }
830
831 void
832-HashQueueTest::tearDown() {
833+test_hash_queue::tearDown() {
834 torrent::taskScheduler.clear();
835-}
836-
837-void
838-HashQueueTest::test_basic() {
839- // SETUP_CHUNK_LIST();
840- // SETUP_THREAD();
841- // thread_disk->start_thread();
842-
843- // torrent::HashQueue* hash_queue = new torrent::HashQueue(thread_disk);
844-
845- // // Do stuff?
846-
847- // delete hash_queue;
848-
849- // thread_disk->stop_thread();
850- // CLEANUP_THREAD();
851- // CLEANUP_CHUNK_LIST();
852+ test_fixture::tearDown();
853 }
854
855 static void
856@@ -73,7 +63,7 @@ fill_queue() {
857 }
858
859 void
860-HashQueueTest::test_single() {
861+test_hash_queue::test_single() {
862 SETUP_CHUNK_LIST();
863 SETUP_THREAD();
864 thread_disk->start_thread();
865@@ -105,7 +95,7 @@ HashQueueTest::test_single() {
866 }
867
868 void
869-HashQueueTest::test_multiple() {
870+test_hash_queue::test_multiple() {
871 SETUP_CHUNK_LIST();
872 SETUP_THREAD();
873 thread_disk->start_thread();
874@@ -137,7 +127,7 @@ HashQueueTest::test_multiple() {
875 }
876
877 void
878-HashQueueTest::test_erase() {
879+test_hash_queue::test_erase() {
880 SETUP_CHUNK_LIST();
881 SETUP_THREAD();
882
883@@ -164,7 +154,7 @@ HashQueueTest::test_erase() {
884 }
885
886 void
887-HashQueueTest::test_erase_stress() {
888+test_hash_queue::test_erase_stress() {
889 SETUP_CHUNK_LIST();
890 SETUP_THREAD();
891 thread_disk->start_thread();
892diff --git a/test/data/hash_queue_test.h b/test/data/test_hash_queue.h
893similarity index 58%
894rename from test/data/hash_queue_test.h
895rename to test/data/test_hash_queue.h
896index cb5b7282..79914484 100644
897--- a/test/data/hash_queue_test.h
898+++ b/test/data/test_hash_queue.h
899@@ -1,10 +1,7 @@
900-#include <cppunit/extensions/HelperMacros.h>
901+#include "helpers/test_fixture.h"
902
903-#include "data/hash_queue.h"
904-
905-class HashQueueTest : public CppUnit::TestFixture {
906- CPPUNIT_TEST_SUITE(HashQueueTest);
907- CPPUNIT_TEST(test_basic);
908+class test_hash_queue : public test_fixture {
909+ CPPUNIT_TEST_SUITE(test_hash_queue);
910
911 CPPUNIT_TEST(test_single);
912 CPPUNIT_TEST(test_multiple);
913@@ -17,8 +14,6 @@ public:
914 void setUp();
915 void tearDown();
916
917- void test_basic();
918-
919 void test_single();
920 void test_multiple();
921 void test_erase();
922diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc
923index c2b60bcd..7a6ed047 100644
924--- a/test/helpers/progress_listener.cc
925+++ b/test/helpers/progress_listener.cc
926@@ -36,10 +36,10 @@ progress_listener::addFailure(const CppUnit::TestFailure &failure) {
927 if (m_current_log_buffer == nullptr)
928 return;
929
930- std::cout << " : " << (failure.isError() ? "error" : "assertion");
931+ std::cout << " : " << (failure.isError() ? "error" : "assertion") << std::flush;
932
933 m_last_test_failed = true;
934- m_failures.push_back(std::move(failure_type{failure.failedTestName(), std::move(m_current_log_buffer)}));
935+ m_failures.push_back(failure_type{ failure.failedTestName(), std::move(m_current_log_buffer) });
936 }
937
938 void
939diff --git a/test/helpers/test_fixture.h b/test/helpers/test_fixture.h
940index 312d5009..aa557a5e 100644
941--- a/test/helpers/test_fixture.h
942+++ b/test/helpers/test_fixture.h
943@@ -1,14 +1,14 @@
944-#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H
945-#define LIBTORRENT_HELPER_TEST_FIXTURE_H
946-
947-#include <cppunit/extensions/HelperMacros.h>
948-
949-#include "helpers/mock_function.h"
950-
951-class test_fixture : public CppUnit::TestFixture {
952-public:
953- void setUp();
954- void tearDown();
955-};
956-
957-#endif
958+#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H
959+#define LIBTORRENT_HELPER_TEST_FIXTURE_H
960+
961+#include <cppunit/extensions/HelperMacros.h>
962+
963+#include "helpers/mock_function.h"
964+
965+class test_fixture : public CppUnit::TestFixture {
966+public:
967+ void setUp();
968+ void tearDown();
969+};
970+
971+#endif
972diff --git a/test/helpers/test_thread.cc b/test/helpers/test_thread.cc
973new file mode 100755
974index 00000000..4b3d4c95
975--- /dev/null
976+++ b/test/helpers/test_thread.cc
977@@ -0,0 +1,71 @@
978+#import "config.h"
979+
980+#import "test_thread.h"
981+
982+#import <unistd.h>
983+#import <cppunit/extensions/HelperMacros.h>
984+
985+#import "thread_disk.h"
986+#import "torrent/exceptions.h"
987+#import "torrent/poll_select.h"
988+
989+const int test_thread::test_flag_pre_stop;
990+const int test_thread::test_flag_long_timeout;
991+
992+const int test_thread::test_flag_acquire_global;
993+const int test_thread::test_flag_has_global;
994+
995+const int test_thread::test_flag_do_work;
996+const int test_thread::test_flag_pre_poke;
997+const int test_thread::test_flag_post_poke;
998+
999+test_thread::test_thread() :
1000+ m_test_state(TEST_NONE),
1001+ m_test_flags(0) {
1002+}
1003+
1004+void
1005+test_thread::init_thread() {
1006+ m_state = STATE_INITIALIZED;
1007+ m_test_state = TEST_PRE_START;
1008+ m_poll = torrent::PollSelect::create(256);
1009+}
1010+
1011+void
1012+test_thread::call_events() {
1013+ if ((m_test_flags & test_flag_pre_stop) && m_test_state == TEST_PRE_START && m_state == STATE_ACTIVE)
1014+ __sync_lock_test_and_set(&m_test_state, TEST_PRE_STOP);
1015+
1016+ if ((m_test_flags & test_flag_acquire_global)) {
1017+ acquire_global_lock();
1018+ __sync_and_and_fetch(&m_test_flags, ~test_flag_acquire_global);
1019+ __sync_or_and_fetch(&m_test_flags, test_flag_has_global);
1020+ }
1021+
1022+ if ((m_flags & flag_do_shutdown)) {
1023+ if ((m_flags & flag_did_shutdown))
1024+ throw torrent::internal_error("Already trigged shutdown.");
1025+
1026+ __sync_or_and_fetch(&m_flags, flag_did_shutdown);
1027+ throw torrent::shutdown_exception();
1028+ }
1029+
1030+ if ((m_test_flags & test_flag_pre_poke)) {
1031+ }
1032+
1033+ if ((m_test_flags & test_flag_do_work)) {
1034+ usleep(10 * 1000); // TODO: Don't just sleep, as that give up core.
1035+ __sync_and_and_fetch(&m_test_flags, ~test_flag_do_work);
1036+ }
1037+
1038+ if ((m_test_flags & test_flag_post_poke)) {
1039+ }
1040+}
1041+
1042+thread_management_type::thread_management_type() {
1043+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
1044+}
1045+
1046+thread_management_type::~thread_management_type() {
1047+ torrent::thread_base::release_global_lock();
1048+}
1049diff --git a/test/helpers/test_thread.h b/test/helpers/test_thread.h
1050new file mode 100755
1051index 00000000..52037036
1052--- /dev/null
1053+++ b/test/helpers/test_thread.h
1054@@ -0,0 +1,59 @@
1055+#import "torrent/utils/thread_base.h"
1056+
1057+class test_thread : public torrent::thread_base {
1058+public:
1059+ enum test_state {
1060+ TEST_NONE,
1061+ TEST_PRE_START,
1062+ TEST_PRE_STOP,
1063+ TEST_STOP
1064+ };
1065+
1066+ static const int test_flag_pre_stop = 0x1;
1067+ static const int test_flag_long_timeout = 0x2;
1068+
1069+ static const int test_flag_acquire_global = 0x10;
1070+ static const int test_flag_has_global = 0x20;
1071+
1072+ static const int test_flag_do_work = 0x100;
1073+ static const int test_flag_pre_poke = 0x200;
1074+ static const int test_flag_post_poke = 0x400;
1075+
1076+ test_thread();
1077+
1078+ int test_state() const { return m_test_state; }
1079+ bool is_state(int state) const { return m_state == state; }
1080+ bool is_test_state(int state) const { return m_test_state == state; }
1081+ bool is_test_flags(int flags) const { return (m_test_flags & flags) == flags; }
1082+ bool is_not_test_flags(int flags) const { return !(m_test_flags & flags); }
1083+
1084+ auto name() const -> const char* { return "test_thread"; }
1085+
1086+ void init_thread();
1087+
1088+ void set_pre_stop() { __sync_or_and_fetch(&m_test_flags, test_flag_pre_stop); }
1089+ void set_acquire_global() { __sync_or_and_fetch(&m_test_flags, test_flag_acquire_global); }
1090+
1091+ void set_test_flag(int flags) { __sync_or_and_fetch(&m_test_flags, flags); }
1092+
1093+private:
1094+ void call_events();
1095+ int64_t next_timeout_usec() { return (m_test_flags & test_flag_long_timeout) ? (10000 * 1000) : (100 * 1000); }
1096+
1097+ int m_test_state lt_cacheline_aligned;
1098+ int m_test_flags lt_cacheline_aligned;
1099+};
1100+
1101+struct thread_management_type {
1102+ thread_management_type();
1103+ ~thread_management_type();
1104+};
1105+
1106+#define SETUP_THREAD() \
1107+ thread_management_type thread_management; \
1108+ torrent::thread_disk* thread_disk = new torrent::thread_disk(); \
1109+ thread_disk->init_thread();
1110+
1111+#define CLEANUP_THREAD() \
1112+ CPPUNIT_ASSERT(wait_for_true(std::bind(&torrent::thread_base::is_inactive, thread_disk))); \
1113+ delete thread_disk;
1114diff --git a/test/helpers/test_utils.h b/test/helpers/test_utils.h
1115new file mode 100644
1116index 00000000..0c8c6b7a
1117--- /dev/null
1118+++ b/test/helpers/test_utils.h
1119@@ -0,0 +1,16 @@
1120+#include <functional>
1121+#include <unistd.h>
1122+
1123+inline bool
1124+wait_for_true(std::function<bool ()> test_function) {
1125+ int i = 100;
1126+
1127+ do {
1128+ if (test_function())
1129+ return true;
1130+
1131+ usleep(10 * 1000);
1132+ } while (--i);
1133+
1134+ return false;
1135+}
1136diff --git a/test/helpers/utils.h b/test/helpers/utils.h
1137index d18450c1..e81d22eb 100644
1138--- a/test/helpers/utils.h
1139+++ b/test/helpers/utils.h
1140@@ -1,60 +1,60 @@
1141-#ifndef LIBTORRENT_HELPER_UTILS_H
1142-#define LIBTORRENT_HELPER_UTILS_H
1143-
1144-#include <algorithm>
1145-#include <iostream>
1146-#include <cppunit/extensions/TestFactoryRegistry.h>
1147-#include <torrent/utils/log.h>
1148-
1149-static void
1150-dump_failure_log(const failure_type& failure) {
1151- if (failure.log->empty())
1152- return;
1153-
1154- std::cout << std::endl << failure.name << std::endl;
1155-
1156- // Doesn't print dump messages as log_buffer drops them.
1157- std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) {
1158- std::cout << entry.timestamp << ' ' << entry.message << '\n';
1159- });
1160-
1161- std::cout << std::flush;
1162-}
1163-
1164-static void
1165-dump_failures(const failure_list_type& failures) {
1166- if (failures.empty())
1167- return;
1168-
1169- std::cout << std::endl
1170- << "=================" << std::endl
1171- << "Failed Test Logs:" << std::endl
1172- << "=================" << std::endl;
1173-
1174- std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) {
1175- dump_failure_log(failure);
1176- });
1177- std::cout << std::endl;
1178-}
1179-
1180-static
1181-void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) {
1182- if (c_test_names == NULL || std::string(c_test_names).empty()) {
1183- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
1184- return;
1185- }
1186-
1187- const std::string& test_names(c_test_names);
1188-
1189- size_t pos = 0;
1190- size_t next = 0;
1191-
1192- while ((next = test_names.find(',', pos)) < test_names.size()) {
1193- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest());
1194- pos = next + 1;
1195- }
1196-
1197- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest());
1198-}
1199-
1200-#endif
1201+#ifndef LIBTORRENT_HELPER_UTILS_H
1202+#define LIBTORRENT_HELPER_UTILS_H
1203+
1204+#include <algorithm>
1205+#include <iostream>
1206+#include <cppunit/extensions/TestFactoryRegistry.h>
1207+#include <torrent/utils/log.h>
1208+
1209+static void
1210+dump_failure_log(const failure_type& failure) {
1211+ if (failure.log->empty())
1212+ return;
1213+
1214+ std::cout << std::endl << failure.name << std::endl;
1215+
1216+ // Doesn't print dump messages as log_buffer drops them.
1217+ std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) {
1218+ std::cout << entry.timestamp << ' ' << entry.message << '\n';
1219+ });
1220+
1221+ std::cout << std::flush;
1222+}
1223+
1224+static void
1225+dump_failures(const failure_list_type& failures) {
1226+ if (failures.empty())
1227+ return;
1228+
1229+ std::cout << std::endl
1230+ << "=================" << std::endl
1231+ << "Failed Test Logs:" << std::endl
1232+ << "=================" << std::endl;
1233+
1234+ std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) {
1235+ dump_failure_log(failure);
1236+ });
1237+ std::cout << std::endl;
1238+}
1239+
1240+static
1241+void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) {
1242+ if (c_test_names == NULL || std::string(c_test_names).empty()) {
1243+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
1244+ return;
1245+ }
1246+
1247+ const std::string& test_names(c_test_names);
1248+
1249+ size_t pos = 0;
1250+ size_t next = 0;
1251+
1252+ while ((next = test_names.find(',', pos)) < test_names.size()) {
1253+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest());
1254+ pos = next + 1;
1255+ }
1256+
1257+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest());
1258+}
1259+
1260+#endif
1261diff --git a/test/main.cc b/test/main.cc
1262index e8a00e1f..57ae31a2 100644
1263--- a/test/main.cc
1264+++ b/test/main.cc
1265@@ -19,9 +19,11 @@
1266 #include "helpers/progress_listener.h"
1267 #include "helpers/utils.h"
1268
1269-CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net");
1270 CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/net");
1271 CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/utils");
1272+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent");
1273+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net");
1274+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("tracker");
1275
1276 void
1277 do_test_panic(int signum) {
1278diff --git a/test/torrent/http_test.cc b/test/torrent/test_http.cc
1279similarity index 94%
1280rename from test/torrent/http_test.cc
1281rename to test/torrent/test_http.cc
1282index 27e04552..24ec97b5 100644
1283--- a/test/torrent/http_test.cc
1284+++ b/test/torrent/test_http.cc
1285@@ -1,10 +1,11 @@
1286 #include "config.h"
1287
1288-#include <sstream>
1289+#include "test_http.h"
1290
1291-#include "http_test.h"
1292+#include <sstream>
1293+#include "torrent/http.h"
1294
1295-CPPUNIT_TEST_SUITE_REGISTRATION(HttpTest);
1296+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_http, "torrent");
1297
1298 #define HTTP_SETUP() \
1299 bool http_destroyed = false; \
1300@@ -72,7 +73,7 @@ TestHttp* create_test_http() { return new TestHttp; }
1301 static void increment_value(int* value) { (*value)++; }
1302
1303 void
1304-HttpTest::test_basic() {
1305+test_http::test_basic() {
1306 torrent::Http::slot_factory() = std::bind(&create_test_http);
1307
1308 torrent::Http* http = torrent::Http::slot_factory()();
1309@@ -94,7 +95,7 @@ HttpTest::test_basic() {
1310 }
1311
1312 void
1313-HttpTest::test_done() {
1314+test_http::test_done() {
1315 HTTP_SETUP();
1316 http->start();
1317
1318@@ -106,7 +107,7 @@ HttpTest::test_done() {
1319 }
1320
1321 void
1322-HttpTest::test_failure() {
1323+test_http::test_failure() {
1324 HTTP_SETUP();
1325 http->start();
1326
1327@@ -118,7 +119,7 @@ HttpTest::test_failure() {
1328 }
1329
1330 void
1331-HttpTest::test_delete_on_done() {
1332+test_http::test_delete_on_done() {
1333 HTTP_SETUP();
1334 http->start();
1335 http->set_delete_stream();
1336@@ -145,7 +146,7 @@ HttpTest::test_delete_on_done() {
1337 }
1338
1339 void
1340-HttpTest::test_delete_on_failure() {
1341+test_http::test_delete_on_failure() {
1342 HTTP_SETUP();
1343 http->start();
1344 http->set_delete_stream();
1345diff --git a/test/torrent/http_test.h b/test/torrent/test_http.h
1346similarity index 63%
1347rename from test/torrent/http_test.h
1348rename to test/torrent/test_http.h
1349index c6c97d08..f4334646 100644
1350--- a/test/torrent/http_test.h
1351+++ b/test/torrent/test_http.h
1352@@ -1,21 +1,18 @@
1353-#include <cppunit/extensions/HelperMacros.h>
1354+#import "helpers/test_fixture.h"
1355
1356-#include "torrent/http.h"
1357+class test_http : public test_fixture {
1358+ CPPUNIT_TEST_SUITE(test_http);
1359
1360-class HttpTest : public CppUnit::TestFixture {
1361- CPPUNIT_TEST_SUITE(HttpTest);
1362 CPPUNIT_TEST(test_basic);
1363 CPPUNIT_TEST(test_done);
1364 CPPUNIT_TEST(test_failure);
1365
1366 CPPUNIT_TEST(test_delete_on_done);
1367 CPPUNIT_TEST(test_delete_on_failure);
1368+
1369 CPPUNIT_TEST_SUITE_END();
1370
1371 public:
1372- void setUp() {}
1373- void tearDown() {}
1374-
1375 void test_basic();
1376 void test_done();
1377 void test_failure();
1378diff --git a/test/torrent/utils/option_strings_test.h b/test/torrent/utils/option_strings_test.h
1379deleted file mode 100644
1380index 55df4f19..00000000
1381--- a/test/torrent/utils/option_strings_test.h
1382+++ /dev/null
1383@@ -1,17 +0,0 @@
1384-#include <cppunit/extensions/HelperMacros.h>
1385-
1386-#include "torrent/utils/option_strings.h"
1387-
1388-class option_strings_test : public CppUnit::TestFixture {
1389- CPPUNIT_TEST_SUITE(option_strings_test);
1390- CPPUNIT_TEST(test_basic);
1391- CPPUNIT_TEST(test_entries);
1392- CPPUNIT_TEST_SUITE_END();
1393-
1394-public:
1395- void setUp() {}
1396- void tearDown() {}
1397-
1398- void test_basic();
1399- void test_entries();
1400-};
1401diff --git a/test/torrent/utils/signal_bitfield_test.h b/test/torrent/utils/signal_bitfield_test.h
1402deleted file mode 100644
1403index 4590de41..00000000
1404--- a/test/torrent/utils/signal_bitfield_test.h
1405+++ /dev/null
1406@@ -1,23 +0,0 @@
1407-#include <cppunit/extensions/HelperMacros.h>
1408-
1409-#include "torrent/utils/signal_bitfield.h"
1410-
1411-class utils_signal_bitfield_test : public CppUnit::TestFixture {
1412- CPPUNIT_TEST_SUITE(utils_signal_bitfield_test);
1413- CPPUNIT_TEST(test_basic);
1414- CPPUNIT_TEST(test_single);
1415- CPPUNIT_TEST(test_multiple);
1416-
1417- CPPUNIT_TEST(test_thread);
1418- CPPUNIT_TEST_SUITE_END();
1419-
1420-public:
1421- void setUp();
1422- void tearDown();
1423-
1424- void test_basic();
1425- void test_single();
1426- void test_multiple();
1427-
1428- void test_thread();
1429-};
1430diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc
1431index 87424d62..8e614e10 100644
1432--- a/test/torrent/utils/test_extents.cc
1433+++ b/test/torrent/utils/test_extents.cc
1434@@ -2,34 +2,25 @@
1435
1436 #include "test_extents.h"
1437
1438-#include <cinttypes>
1439-#include <iostream>
1440 #include <torrent/utils/extents.h>
1441+#include <torrent/utils/log.h>
1442
1443-CPPUNIT_TEST_SUITE_REGISTRATION(ExtentsTest);
1444+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_extents, "torrent/utils");
1445
1446-void
1447-ExtentsTest::setUp() {
1448-}
1449+#define TEST_EXTENT_BEGIN(name) \
1450+ lt_log_print(torrent::LOG_MOCK_CALLS, "extent: %s", name);
1451
1452-void
1453-ExtentsTest::tearDown() {
1454-}
1455-
1456-//typedef torrent::extents<uint32_t, int, 8, 16, 4> extent_type_1;
1457 typedef torrent::extents<uint32_t, int> extent_type_1;
1458
1459-// typedef torrent::extents<uint32_t, int, 0, 256, 16> extent_type_3;
1460-/*
1461 template <typename Extent>
1462 bool
1463 verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) {
1464 while (*idx != *(idx + 1)) {
1465- if (!extent.is_equal_range(*idx, *(idx + 1) - 1, *val)) {
1466- // std::cout << *idx << ' ' << *(idx + 1) << ' ' << *val << std::endl;
1467- // std::cout << extent.at(*idx) << std::endl;
1468- // std::cout << extent.at(*(idx + 1)) << std::endl;
1469- return false;
1470+ for (auto i = *idx; i != *(idx + 1); i++) {
1471+ lt_log_print(torrent::LOG_MOCK_CALLS, "extent: at %u", i);
1472+
1473+ if (extent.at(i) != *val)
1474+ return false;
1475 }
1476
1477 idx++;
1478@@ -40,34 +31,32 @@ verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) {
1479 }
1480
1481 static const uint32_t idx_empty[] = {0, 256, 256};
1482-static const int val_empty[] = {0, 1};
1483+static const int val_empty[] = {0};
1484
1485 static const uint32_t idx_basic_1[] = {0, 1, 255, 256, 256};
1486 static const int val_basic_1[] = {1, 0, 1};
1487
1488-// static const uint32_t idx_basic_2[] = {0, 1, 16, 255, 256, 256};
1489-// static const int val_basic_2[] = {1, 0, 2, 1};
1490-*/
1491 void
1492-ExtentsTest::test_basic() {
1493+test_extents::test_basic() {
1494 extent_type_1 extent_1;
1495-/*
1496- // Test empty.
1497- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty));
1498-
1499- CPPUNIT_ASSERT(extent_1.at(0) == int());
1500- CPPUNIT_ASSERT(extent_1.at(255) == int());
1501+ extent_1.insert(0, 255, int());
1502
1503- extent_1.insert(0, 0, 1);
1504- extent_1.insert(255, 0, 1);
1505+ { TEST_EXTENT_BEGIN("empty");
1506+ CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty));
1507
1508- CPPUNIT_ASSERT(extent_1.at(0) == 1);
1509- CPPUNIT_ASSERT(extent_1.at(255) == 1);
1510+ CPPUNIT_ASSERT(extent_1.at(0) == int());
1511+ CPPUNIT_ASSERT(extent_1.at(255) == int());
1512+ };
1513+ { TEST_EXTENT_BEGIN("borders");
1514
1515- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_1, val_basic_1));
1516+ extent_1.insert(0, 0, 1);
1517+ extent_1.insert(255, 255, 1);
1518+ // This step shouldn't be needed.
1519+ extent_1.insert(1, 254, int());
1520
1521- // extent_1.insert(38, 3, 2);
1522+ CPPUNIT_ASSERT(extent_1.at(0) == 1);
1523+ CPPUNIT_ASSERT(extent_1.at(255) == 1);
1524
1525- // CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_2, val_basic_2));
1526-*/
1527+ CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_1, val_basic_1));
1528+ };
1529 }
1530diff --git a/test/torrent/utils/test_extents.h b/test/torrent/utils/test_extents.h
1531index fd790cf8..e187f6a7 100644
1532--- a/test/torrent/utils/test_extents.h
1533+++ b/test/torrent/utils/test_extents.h
1534@@ -1,13 +1,10 @@
1535-#include <cppunit/extensions/HelperMacros.h>
1536+#include "helpers/test_fixture.h"
1537
1538-class ExtentsTest : public CppUnit::TestFixture {
1539- CPPUNIT_TEST_SUITE(ExtentsTest);
1540+class test_extents : public test_fixture {
1541+ CPPUNIT_TEST_SUITE(test_extents);
1542 CPPUNIT_TEST(test_basic);
1543 CPPUNIT_TEST_SUITE_END();
1544
1545 public:
1546- void setUp();
1547- void tearDown();
1548-
1549 void test_basic();
1550 };
1551diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/test_log.cc
1552similarity index 92%
1553rename from test/torrent/utils/log_test.cc
1554rename to test/torrent/utils/test_log.cc
1555index 8cc00ef8..fec7e505 100644
1556--- a/test/torrent/utils/log_test.cc
1557+++ b/test/torrent/utils/test_log.cc
1558@@ -1,5 +1,7 @@
1559 #include "config.h"
1560
1561+#include "test_log.h"
1562+
1563 #include <algorithm>
1564 #include <cstring>
1565 #include <fstream>
1566@@ -9,15 +11,13 @@
1567 #include <torrent/exceptions.h>
1568 #include <torrent/utils/log.h>
1569
1570-#include "log_test.h"
1571+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log, "torrent/utils");
1572
1573 namespace torrent {
1574 typedef std::vector<std::pair<std::string, log_slot> > log_output_list;
1575 extern log_output_list log_outputs;
1576 }
1577
1578-CPPUNIT_TEST_SUITE_REGISTRATION(utils_log_test);
1579-
1580 const char* expected_output = NULL;
1581 unsigned int output_mask;
1582
1583@@ -35,19 +35,19 @@ test_output(const char* output, unsigned int length, unsigned int mask) {
1584 CPPUNIT_ASSERT(output_mask == (mask));
1585
1586 void
1587-utils_log_test::setUp() {
1588+test_log::setUp() {
1589 // Don't initialize since this creates the group->child connections.
1590 // torrent::log_initialize();
1591 torrent::log_cleanup();
1592 }
1593
1594 void
1595-utils_log_test::tearDown() {
1596+test_log::tearDown() {
1597 torrent::log_cleanup();
1598 }
1599
1600 void
1601-utils_log_test::test_basic() {
1602+test_log::test_basic() {
1603 CPPUNIT_ASSERT(!torrent::log_groups.empty());
1604 CPPUNIT_ASSERT(torrent::log_groups.size() == torrent::LOG_GROUP_MAX_SIZE);
1605
1606@@ -61,7 +61,7 @@ open_output(const char* name, int mask = 0) {
1607 }
1608
1609 void
1610-utils_log_test::test_output_open() {
1611+test_log::test_output_open() {
1612 CPPUNIT_ASSERT(torrent::log_groups[0].size_outputs() == 0);
1613
1614 // Add test for unknown output names.
1615@@ -92,7 +92,7 @@ utils_log_test::test_output_open() {
1616 // on unused log items.
1617
1618 void
1619-utils_log_test::test_print() {
1620+test_log::test_print() {
1621 open_output("test_print_1", 0x1);
1622 open_output("test_print_2", 0x2);
1623 torrent::log_add_group_output(0, "test_print_1");
1624@@ -113,7 +113,7 @@ enum {
1625 };
1626
1627 void
1628-utils_log_test::test_children() {
1629+test_log::test_children() {
1630 open_output("test_children_1", 0x1);
1631 open_output("test_children_2", 0x2);
1632 torrent::log_add_group_output(GROUP_PARENT_1, "test_children_1");
1633@@ -136,8 +136,8 @@ utils_log_test::test_children() {
1634 }
1635
1636 void
1637-utils_log_test::test_file_output() {
1638- std::string filename = "utils_log_test.XXXXXX";
1639+test_log::test_file_output() {
1640+ std::string filename = "test_log.XXXXXX";
1641
1642 mktemp(&*filename.begin());
1643
1644@@ -159,8 +159,8 @@ utils_log_test::test_file_output() {
1645 }
1646
1647 void
1648-utils_log_test::test_file_output_append() {
1649- std::string filename = "utils_log_test.XXXXXX";
1650+test_log::test_file_output_append() {
1651+ std::string filename = "test_log.XXXXXX";
1652
1653 mktemp(&*filename.begin());
1654
1655diff --git a/test/torrent/utils/log_test.h b/test/torrent/utils/test_log.h
1656similarity index 71%
1657rename from test/torrent/utils/log_test.h
1658rename to test/torrent/utils/test_log.h
1659index d4cb3bc6..a06c95ae 100644
1660--- a/test/torrent/utils/log_test.h
1661+++ b/test/torrent/utils/test_log.h
1662@@ -1,9 +1,7 @@
1663-#include <cppunit/extensions/HelperMacros.h>
1664+#include "helpers/test_fixture.h"
1665
1666-#include "torrent/utils/log.h"
1667-
1668-class utils_log_test : public CppUnit::TestFixture {
1669- CPPUNIT_TEST_SUITE(utils_log_test);
1670+class test_log : public test_fixture {
1671+ CPPUNIT_TEST_SUITE(test_log);
1672 CPPUNIT_TEST(test_basic);
1673 CPPUNIT_TEST(test_output_open);
1674
1675diff --git a/test/torrent/utils/test_log_buffer.cc b/test/torrent/utils/test_log_buffer.cc
1676index a56a5365..58412750 100644
1677--- a/test/torrent/utils/test_log_buffer.cc
1678+++ b/test/torrent/utils/test_log_buffer.cc
1679@@ -7,18 +7,10 @@
1680
1681 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log_buffer, "torrent/utils");
1682
1683-void
1684-test_log_buffer::setUp() {
1685- torrent::cachedTime = rak::timer::from_seconds(1000);
1686-}
1687-
1688-void
1689-test_log_buffer::tearDown() {
1690-}
1691-
1692 void
1693 test_log_buffer::test_basic() {
1694 torrent::log_buffer log;
1695+ torrent::cachedTime = rak::timer::from_seconds(1000);
1696
1697 log.lock();
1698 CPPUNIT_ASSERT(log.empty());
1699@@ -46,6 +38,7 @@ test_log_buffer::test_basic() {
1700 void
1701 test_log_buffer::test_timestamps() {
1702 torrent::log_buffer log;
1703+ torrent::cachedTime = rak::timer::from_seconds(1000);
1704
1705 log.lock_and_push_log("foobar", 6, 0);
1706 CPPUNIT_ASSERT(log.back().timestamp == 1000);
1707diff --git a/test/torrent/utils/test_log_buffer.h b/test/torrent/utils/test_log_buffer.h
1708index 290df4c1..39c6b879 100644
1709--- a/test/torrent/utils/test_log_buffer.h
1710+++ b/test/torrent/utils/test_log_buffer.h
1711@@ -2,16 +2,11 @@
1712
1713 class test_log_buffer : public test_fixture {
1714 CPPUNIT_TEST_SUITE(test_log_buffer);
1715-
1716 CPPUNIT_TEST(test_basic);
1717 CPPUNIT_TEST(test_timestamps);
1718-
1719 CPPUNIT_TEST_SUITE_END();
1720
1721 public:
1722- void setUp();
1723- void tearDown();
1724-
1725 void test_basic();
1726 void test_timestamps();
1727 };
1728diff --git a/test/torrent/utils/option_strings_test.cc b/test/torrent/utils/test_option_strings.cc
1729similarity index 65%
1730rename from test/torrent/utils/option_strings_test.cc
1731rename to test/torrent/utils/test_option_strings.cc
1732index a9bdcc89..68da1d2b 100644
1733--- a/test/torrent/utils/option_strings_test.cc
1734+++ b/test/torrent/utils/test_option_strings.cc
1735@@ -1,35 +1,22 @@
1736 #include "config.h"
1737
1738-#include <fstream>
1739-#include <functional>
1740-#include <iostream>
1741+#include "test_option_strings.h"
1742
1743-#include <torrent/exceptions.h>
1744-#include <torrent/utils/option_strings.h>
1745-
1746-#include <torrent/connection_manager.h>
1747-#include <torrent/object.h>
1748 #include <torrent/download.h>
1749-#include <torrent/download/choke_group.h>
1750-#include <torrent/download/choke_queue.h>
1751+#include <torrent/utils/option_strings.h>
1752 #include <torrent/utils/log.h>
1753
1754-#include "option_strings_test.h"
1755-
1756-CPPUNIT_TEST_SUITE_REGISTRATION(option_strings_test);
1757-
1758-void
1759-option_strings_test::test_basic() {
1760-
1761-}
1762+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_option_strings, "torrent/utils");
1763
1764 #define TEST_ENTRY(group, name, value) \
1765- { std::string result(torrent::option_as_string(torrent::group, value)); \
1766+ { lt_log_print(torrent::LOG_MOCK_CALLS, "option_string: %s", name); \
1767+ std::string result(torrent::option_as_string(torrent::group, value)); \
1768 CPPUNIT_ASSERT_MESSAGE("Not found '" + result + "'", result == name); \
1769- CPPUNIT_ASSERT(torrent::option_find_string(torrent::group, name) == value); }
1770+ CPPUNIT_ASSERT(torrent::option_find_string(torrent::group, name) == value); \
1771+ }
1772
1773 void
1774-option_strings_test::test_entries() {
1775+test_option_strings::test_entries() {
1776 TEST_ENTRY(OPTION_CONNECTION_TYPE, "leech", torrent::Download::CONNECTION_LEECH);
1777 TEST_ENTRY(OPTION_CONNECTION_TYPE, "seed", torrent::Download::CONNECTION_SEED);
1778 TEST_ENTRY(OPTION_CONNECTION_TYPE, "initial_seed", torrent::Download::CONNECTION_INITIAL_SEED);
1779diff --git a/test/torrent/utils/test_option_strings.h b/test/torrent/utils/test_option_strings.h
1780new file mode 100644
1781index 00000000..dc86e735
1782--- /dev/null
1783+++ b/test/torrent/utils/test_option_strings.h
1784@@ -0,0 +1,10 @@
1785+#include "helpers/test_fixture.h"
1786+
1787+class test_option_strings : public test_fixture {
1788+ CPPUNIT_TEST_SUITE(test_option_strings);
1789+ CPPUNIT_TEST(test_entries);
1790+ CPPUNIT_TEST_SUITE_END();
1791+
1792+public:
1793+ void test_entries();
1794+};
1795diff --git a/test/torrent/utils/test_queue_buckets.cc b/test/torrent/utils/test_queue_buckets.cc
1796index a32d17e7..49d1bae6 100644
1797--- a/test/torrent/utils/test_queue_buckets.cc
1798+++ b/test/torrent/utils/test_queue_buckets.cc
1799@@ -5,7 +5,7 @@
1800 #include "utils/instrumentation.h"
1801 #include "utils/queue_buckets.h"
1802
1803-CPPUNIT_TEST_SUITE_REGISTRATION(TestQueueBuckets);
1804+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_queue_buckets, "torrent/utils");
1805
1806 struct test_constants {
1807 static const int bucket_count = 2;
1808@@ -87,7 +87,7 @@ struct test_queue_bucket_compare {
1809 //
1810
1811 void
1812-TestQueueBuckets::test_basic() {
1813+test_queue_buckets::test_basic() {
1814 torrent::instrumentation_initialize();
1815
1816 buckets_type buckets;
1817@@ -129,7 +129,7 @@ TestQueueBuckets::test_basic() {
1818 }
1819
1820 void
1821-TestQueueBuckets::test_erase() {
1822+test_queue_buckets::test_erase() {
1823 items_destroyed = 0;
1824 torrent::instrumentation_initialize();
1825
1826@@ -162,7 +162,7 @@ bucket_queue_find_in_any(const buckets_type& buckets, int value) {
1827 }
1828
1829 void
1830-TestQueueBuckets::test_find() {
1831+test_queue_buckets::test_find() {
1832 items_destroyed = 0;
1833 torrent::instrumentation_initialize();
1834
1835@@ -183,7 +183,7 @@ TestQueueBuckets::test_find() {
1836 }
1837
1838 void
1839-TestQueueBuckets::test_destroy_range() {
1840+test_queue_buckets::test_destroy_range() {
1841 items_destroyed = 0;
1842 torrent::instrumentation_initialize();
1843
1844@@ -206,7 +206,7 @@ TestQueueBuckets::test_destroy_range() {
1845 }
1846
1847 void
1848-TestQueueBuckets::test_move_range() {
1849+test_queue_buckets::test_move_range() {
1850 items_destroyed = 0;
1851 torrent::instrumentation_initialize();
1852
1853diff --git a/test/torrent/utils/test_queue_buckets.h b/test/torrent/utils/test_queue_buckets.h
1854index 94624573..a7f1c30a 100644
1855--- a/test/torrent/utils/test_queue_buckets.h
1856+++ b/test/torrent/utils/test_queue_buckets.h
1857@@ -1,21 +1,18 @@
1858-#include <cppunit/extensions/HelperMacros.h>
1859+#include "helpers/test_fixture.h"
1860
1861-#include "protocol/request_list.h"
1862+class test_queue_buckets : public test_fixture {
1863+ CPPUNIT_TEST_SUITE(test_queue_buckets);
1864
1865-class TestQueueBuckets : public CppUnit::TestFixture {
1866- CPPUNIT_TEST_SUITE(TestQueueBuckets);
1867 CPPUNIT_TEST(test_basic);
1868 CPPUNIT_TEST(test_erase);
1869 CPPUNIT_TEST(test_find);
1870
1871 CPPUNIT_TEST(test_destroy_range);
1872 CPPUNIT_TEST(test_move_range);
1873+
1874 CPPUNIT_TEST_SUITE_END();
1875
1876 public:
1877- void setUp() {}
1878- void tearDown() {}
1879-
1880 void test_basic();
1881 void test_erase();
1882 void test_find();
1883diff --git a/test/torrent/utils/signal_bitfield_test.cc b/test/torrent/utils/test_signal_bitfield.cc
1884similarity index 85%
1885rename from test/torrent/utils/signal_bitfield_test.cc
1886rename to test/torrent/utils/test_signal_bitfield.cc
1887index 34b622b3..4ecd18c0 100644
1888--- a/test/torrent/utils/signal_bitfield_test.cc
1889+++ b/test/torrent/utils/test_signal_bitfield.cc
1890@@ -1,13 +1,15 @@
1891 #include "config.h"
1892
1893+#include "test_signal_bitfield.h"
1894+
1895+#include "helpers/test_thread.h"
1896+#include "helpers/test_utils.h"
1897+
1898 #include <torrent/exceptions.h>
1899 #include <torrent/utils/signal_bitfield.h>
1900 #include <torrent/utils/thread_base.h>
1901
1902-#include "signal_bitfield_test.h"
1903-#include "thread_base_test.h"
1904-
1905-CPPUNIT_TEST_SUITE_REGISTRATION(utils_signal_bitfield_test);
1906+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_signal_bitfield, "torrent/utils");
1907
1908 static void
1909 mark_index(uint32_t* bitfield, unsigned int index) {
1910@@ -20,13 +22,10 @@ check_index(uint32_t* bitfield, unsigned int index) {
1911 }
1912
1913 void
1914-utils_signal_bitfield_test::setUp() {
1915-}
1916-
1917-void
1918-utils_signal_bitfield_test::tearDown() {
1919+test_signal_bitfield::tearDown() {
1920 CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
1921 torrent::thread_base::release_global_lock();
1922+ test_fixture::tearDown();
1923 }
1924
1925 static bool
1926@@ -54,7 +53,7 @@ verify_did_internal_error(std::function<unsigned int ()> func, bool should_throw
1927 did_throw));
1928
1929 void
1930-utils_signal_bitfield_test::test_basic() {
1931+test_signal_bitfield::test_basic() {
1932 SETUP_SIGNAL_BITFIELD();
1933
1934 CPPUNIT_ASSERT(torrent::signal_bitfield::max_size == sizeof(torrent::signal_bitfield::bitfield_type) * 8);
1935@@ -68,7 +67,7 @@ utils_signal_bitfield_test::test_basic() {
1936 }
1937
1938 void
1939-utils_signal_bitfield_test::test_single() {
1940+test_signal_bitfield::test_single() {
1941 SETUP_SIGNAL_BITFIELD();
1942
1943 CPPUNIT_ASSERT(signal_bitfield.add_signal(std::bind(&mark_index, &marked_bitfield, 0)) == 0);
1944@@ -86,7 +85,7 @@ utils_signal_bitfield_test::test_single() {
1945 }
1946
1947 void
1948-utils_signal_bitfield_test::test_multiple() {
1949+test_signal_bitfield::test_multiple() {
1950 SETUP_SIGNAL_BITFIELD();
1951
1952 for (unsigned int i = 0; i < torrent::signal_bitfield::max_size; i++)
1953@@ -106,10 +105,10 @@ utils_signal_bitfield_test::test_multiple() {
1954 }
1955
1956 void
1957-utils_signal_bitfield_test::test_thread() {
1958+test_signal_bitfield::test_threaded() {
1959 uint32_t marked_bitfield = 0;
1960- thread_test* thread = new thread_test;
1961- // thread->set_test_flag(thread_test::test_flag_long_timeout);
1962+ test_thread* thread = new test_thread;
1963+ // thread->set_test_flag(test_thread::test_flag_long_timeout);
1964
1965 for (unsigned int i = 0; i < torrent::signal_bitfield::max_size; i++)
1966 CPPUNIT_ASSERT(thread->signal_bitfield()->add_signal(std::bind(&mark_index, &marked_bitfield, i)) == i);
1967@@ -131,7 +130,7 @@ utils_signal_bitfield_test::test_thread() {
1968 }
1969
1970 thread->stop_thread();
1971- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
1972+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
1973
1974 delete thread;
1975 }
1976diff --git a/test/torrent/utils/test_signal_bitfield.h b/test/torrent/utils/test_signal_bitfield.h
1977new file mode 100644
1978index 00000000..2d24d955
1979--- /dev/null
1980+++ b/test/torrent/utils/test_signal_bitfield.h
1981@@ -0,0 +1,22 @@
1982+#include "helpers/test_fixture.h"
1983+
1984+class test_signal_bitfield : public test_fixture {
1985+ CPPUNIT_TEST_SUITE(test_signal_bitfield);
1986+
1987+ CPPUNIT_TEST(test_basic);
1988+ CPPUNIT_TEST(test_single);
1989+ CPPUNIT_TEST(test_multiple);
1990+
1991+ CPPUNIT_TEST(test_threaded);
1992+
1993+ CPPUNIT_TEST_SUITE_END();
1994+
1995+public:
1996+ void tearDown();
1997+
1998+ void test_basic();
1999+ void test_single();
2000+ void test_multiple();
2001+
2002+ void test_threaded();
2003+};
2004diff --git a/test/torrent/utils/test_thread_base.cc b/test/torrent/utils/test_thread_base.cc
2005new file mode 100644
2006index 00000000..33519b7c
2007--- /dev/null
2008+++ b/test/torrent/utils/test_thread_base.cc
2009@@ -0,0 +1,169 @@
2010+#include "config.h"
2011+
2012+#include "test_thread_base.h"
2013+
2014+#include "helpers/test_thread.h"
2015+#include "helpers/test_utils.h"
2016+
2017+#include <functional>
2018+#include <unistd.h>
2019+
2020+#include "torrent/exceptions.h"
2021+#include "torrent/poll_select.h"
2022+#include "torrent/utils/log.h"
2023+#include "torrent/utils/thread_base.h"
2024+
2025+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_thread_base, "torrent/utils");
2026+
2027+#define TEST_BEGIN(name) \
2028+ lt_log_print(torrent::LOG_MOCK_CALLS, "thread_base: %s", name); \
2029+
2030+void throw_shutdown_exception() { throw torrent::shutdown_exception(); }
2031+
2032+void
2033+test_thread_base::tearDown() {
2034+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2035+ torrent::thread_base::release_global_lock();
2036+ test_fixture::tearDown();
2037+}
2038+
2039+void
2040+test_thread_base::test_basic() {
2041+ test_thread* thread = new test_thread;
2042+
2043+ CPPUNIT_ASSERT(thread->flags() == 0);
2044+
2045+ CPPUNIT_ASSERT(!thread->is_main_polling());
2046+ CPPUNIT_ASSERT(!thread->is_active());
2047+ CPPUNIT_ASSERT(thread->global_queue_size() == 0);
2048+ CPPUNIT_ASSERT(thread->poll() == NULL);
2049+
2050+ // Check active...
2051+}
2052+
2053+void
2054+test_thread_base::test_lifecycle() {
2055+ test_thread* thread = new test_thread;
2056+
2057+ CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_UNKNOWN);
2058+ CPPUNIT_ASSERT(thread->test_state() == test_thread::TEST_NONE);
2059+
2060+ thread->init_thread();
2061+ CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_INITIALIZED);
2062+ CPPUNIT_ASSERT(thread->is_initialized());
2063+ CPPUNIT_ASSERT(thread->test_state() == test_thread::TEST_PRE_START);
2064+
2065+ thread->set_pre_stop();
2066+ CPPUNIT_ASSERT(!wait_for_true(std::bind(&test_thread::is_test_state, thread, test_thread::TEST_PRE_STOP)));
2067+
2068+ thread->start_thread();
2069+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_ACTIVE)));
2070+ CPPUNIT_ASSERT(thread->is_active());
2071+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_test_state, thread, test_thread::TEST_PRE_STOP)));
2072+
2073+ thread->stop_thread();
2074+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
2075+ CPPUNIT_ASSERT(thread->is_inactive());
2076+
2077+ delete thread;
2078+}
2079+
2080+void
2081+test_thread_base::test_global_lock_basic() {
2082+ test_thread* thread = new test_thread;
2083+
2084+ thread->init_thread();
2085+ thread->start_thread();
2086+
2087+ CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
2088+
2089+ // Acquire main thread...
2090+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2091+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2092+
2093+ torrent::thread_base::release_global_lock();
2094+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2095+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2096+
2097+ torrent::thread_base::release_global_lock();
2098+ torrent::thread_base::acquire_global_lock();
2099+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2100+
2101+ thread->set_acquire_global();
2102+ CPPUNIT_ASSERT(!wait_for_true(std::bind(&test_thread::is_test_flags, thread, test_thread::test_flag_has_global)));
2103+
2104+ torrent::thread_base::release_global_lock();
2105+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_test_flags, thread, test_thread::test_flag_has_global)));
2106+
2107+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2108+ torrent::thread_base::release_global_lock();
2109+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2110+
2111+ // Test waive (loop).
2112+
2113+ CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
2114+
2115+ torrent::thread_base::release_global_lock();
2116+ thread->stop_thread();
2117+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
2118+
2119+ delete thread;
2120+}
2121+
2122+void
2123+test_thread_base::test_interrupt() {
2124+ test_thread* thread = new test_thread;
2125+ thread->set_test_flag(test_thread::test_flag_long_timeout);
2126+
2127+ thread->init_thread();
2128+ thread->start_thread();
2129+
2130+ // Vary the various timeouts.
2131+
2132+ for (int i = 0; i < 100; i++) {
2133+ thread->interrupt();
2134+ usleep(0);
2135+
2136+ thread->set_test_flag(test_thread::test_flag_do_work);
2137+ thread->interrupt();
2138+
2139+ // Wait for flag to clear.
2140+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_not_test_flags, thread, test_thread::test_flag_do_work)));
2141+ }
2142+
2143+ thread->stop_thread();
2144+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
2145+
2146+ delete thread;
2147+}
2148+
2149+void
2150+test_thread_base::test_stop() {
2151+ { TEST_BEGIN("trylock global lock");
2152+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2153+ // torrent::thread_base::acquire_global_lock();
2154+ };
2155+
2156+ for (int i = 0; i < 20; i++) {
2157+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2158+
2159+ test_thread* thread = new test_thread;
2160+ thread->set_test_flag(test_thread::test_flag_do_work);
2161+
2162+ { TEST_BEGIN("init and start thread");
2163+ thread->init_thread();
2164+ thread->start_thread();
2165+ };
2166+
2167+ { TEST_BEGIN("stop and delete thread");
2168+ thread->stop_thread_wait();
2169+ CPPUNIT_ASSERT(thread->is_inactive());
2170+
2171+ delete thread;
2172+ }
2173+ }
2174+
2175+ { TEST_BEGIN("release global lock");
2176+ torrent::thread_base::release_global_lock();
2177+ };
2178+}
2179diff --git a/test/torrent/utils/test_thread_base.h b/test/torrent/utils/test_thread_base.h
2180new file mode 100644
2181index 00000000..7b2a3432
2182--- /dev/null
2183+++ b/test/torrent/utils/test_thread_base.h
2184@@ -0,0 +1,25 @@
2185+#include "helpers/test_fixture.h"
2186+
2187+class test_thread_base : public test_fixture {
2188+ CPPUNIT_TEST_SUITE(test_thread_base);
2189+
2190+ CPPUNIT_TEST(test_basic);
2191+ CPPUNIT_TEST(test_lifecycle);
2192+
2193+ CPPUNIT_TEST(test_global_lock_basic);
2194+ CPPUNIT_TEST(test_interrupt);
2195+ CPPUNIT_TEST(test_stop);
2196+
2197+ CPPUNIT_TEST_SUITE_END();
2198+
2199+public:
2200+ void tearDown();
2201+
2202+ void test_basic();
2203+ void test_lifecycle();
2204+
2205+ void test_global_lock_basic();
2206+ void test_interrupt();
2207+ void test_interrupt_legacy();
2208+ void test_stop();
2209+};
2210diff --git a/test/torrent/utils/test_uri_parser.cc b/test/torrent/utils/test_uri_parser.cc
2211index 1f4bebe8..66d6cda5 100644
2212--- a/test/torrent/utils/test_uri_parser.cc
2213+++ b/test/torrent/utils/test_uri_parser.cc
2214@@ -2,31 +2,22 @@
2215
2216 #include "test_uri_parser.h"
2217
2218-#include <cinttypes>
2219-#include <iostream>
2220+#include <torrent/utils/log.h>
2221 #include <torrent/utils/uri_parser.h>
2222
2223-CPPUNIT_TEST_SUITE_REGISTRATION(UriParserTest);
2224-
2225-void
2226-UriParserTest::setUp() {
2227-}
2228-
2229-void
2230-UriParserTest::tearDown() {
2231-}
2232+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_uri_parser, "torrent/utils");
2233
2234 void
2235 test_print_uri_state(torrent::utils::uri_state state) {
2236- std::cerr << "state.uri: " << state.uri << std::endl;
2237- std::cerr << "state.scheme: " << state.scheme << std::endl;
2238- std::cerr << "state.resource: " << state.resource << std::endl;
2239- std::cerr << "state.query: " << state.query << std::endl;
2240- std::cerr << "state.fragment: " << state.fragment << std::endl;
2241+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.uri: %s", state.uri.c_str());
2242+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.scheme: %s", state.scheme.c_str());
2243+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.resource: %s", state.resource.c_str());
2244+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.query: %s", state.query.c_str());
2245+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.fragment: %s", state.fragment.c_str());
2246 }
2247
2248 void
2249-UriParserTest::test_basic() {
2250+test_uri_parser::test_basic() {
2251 torrent::utils::uri_state state;
2252
2253 CPPUNIT_ASSERT(state.state == torrent::utils::uri_state::state_empty);
2254@@ -37,7 +28,7 @@ UriParserTest::test_basic() {
2255 #define MAGNET_BASIC "magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"
2256
2257 void
2258-UriParserTest::test_basic_magnet() {
2259+test_uri_parser::test_basic_magnet() {
2260 torrent::utils::uri_state state;
2261
2262 uri_parse_str(MAGNET_BASIC, state);
2263@@ -63,7 +54,7 @@ UriParserTest::test_basic_magnet() {
2264 #define QUERY_MAGNET "magnet:?" QUERY_MAGNET_QUERY
2265
2266 void
2267-UriParserTest::test_query_magnet() {
2268+test_uri_parser::test_query_magnet() {
2269 torrent::utils::uri_state state;
2270 torrent::utils::uri_query_state query_state;
2271
2272@@ -82,7 +73,7 @@ UriParserTest::test_query_magnet() {
2273 uri_parse_query_str(state.query, query_state);
2274
2275 for (auto element : query_state.elements)
2276- std::cerr << "query_element: " << element << std::endl;
2277+ lt_log_print(torrent::LOG_MOCK_CALLS, "query_element: %s", element.c_str());
2278
2279 CPPUNIT_ASSERT(query_state.state == torrent::utils::uri_query_state::state_valid);
2280
2281diff --git a/test/torrent/utils/test_uri_parser.h b/test/torrent/utils/test_uri_parser.h
2282index 4f1c2586..f978c8ad 100644
2283--- a/test/torrent/utils/test_uri_parser.h
2284+++ b/test/torrent/utils/test_uri_parser.h
2285@@ -1,16 +1,15 @@
2286-#include <cppunit/extensions/HelperMacros.h>
2287+#include "helpers/test_fixture.h"
2288+
2289+class test_uri_parser : public test_fixture {
2290+ CPPUNIT_TEST_SUITE(test_uri_parser);
2291
2292-class UriParserTest : public CppUnit::TestFixture {
2293- CPPUNIT_TEST_SUITE(UriParserTest);
2294 CPPUNIT_TEST(test_basic);
2295 CPPUNIT_TEST(test_basic_magnet);
2296 CPPUNIT_TEST(test_query_magnet);
2297+
2298 CPPUNIT_TEST_SUITE_END();
2299
2300 public:
2301- void setUp();
2302- void tearDown();
2303-
2304 void test_basic();
2305 void test_basic_magnet();
2306 void test_query_magnet();
2307diff --git a/test/torrent/utils/thread_base_test.cc b/test/torrent/utils/thread_base_test.cc
2308deleted file mode 100644
2309index 8366c9ba..00000000
2310--- a/test/torrent/utils/thread_base_test.cc
2311+++ /dev/null
2312@@ -1,224 +0,0 @@
2313-#include "config.h"
2314-
2315-#include <functional>
2316-#include <unistd.h>
2317-
2318-#include <torrent/exceptions.h>
2319-#include <torrent/poll_select.h>
2320-#include <torrent/utils/thread_base.h>
2321-
2322-#include "thread_base_test.h"
2323-
2324-CPPUNIT_TEST_SUITE_REGISTRATION(utils_thread_base_test);
2325-
2326-const int thread_test::test_flag_pre_stop;
2327-const int thread_test::test_flag_long_timeout;
2328-
2329-const int thread_test::test_flag_acquire_global;
2330-const int thread_test::test_flag_has_global;
2331-
2332-const int thread_test::test_flag_do_work;
2333-const int thread_test::test_flag_pre_poke;
2334-const int thread_test::test_flag_post_poke;
2335-
2336-void throw_shutdown_exception() { throw torrent::shutdown_exception(); }
2337-
2338-thread_test::thread_test() :
2339- m_test_state(TEST_NONE),
2340- m_test_flags(0) {
2341-}
2342-
2343-void
2344-thread_test::init_thread() {
2345- m_state = STATE_INITIALIZED;
2346- m_test_state = TEST_PRE_START;
2347- m_poll = torrent::PollSelect::create(256);
2348-}
2349-
2350-void
2351-thread_test::call_events() {
2352- if ((m_test_flags & test_flag_pre_stop) && m_test_state == TEST_PRE_START && m_state == STATE_ACTIVE)
2353- __sync_lock_test_and_set(&m_test_state, TEST_PRE_STOP);
2354-
2355- if ((m_test_flags & test_flag_acquire_global)) {
2356- acquire_global_lock();
2357- __sync_and_and_fetch(&m_test_flags, ~test_flag_acquire_global);
2358- __sync_or_and_fetch(&m_test_flags, test_flag_has_global);
2359- }
2360-
2361- if ((m_flags & flag_do_shutdown)) {
2362- if ((m_flags & flag_did_shutdown))
2363- throw torrent::internal_error("Already trigged shutdown.");
2364-
2365- __sync_or_and_fetch(&m_flags, flag_did_shutdown);
2366- throw torrent::shutdown_exception();
2367- }
2368-
2369- if ((m_test_flags & test_flag_pre_poke)) {
2370- }
2371-
2372- if ((m_test_flags & test_flag_do_work)) {
2373- usleep(10 * 1000); // TODO: Don't just sleep, as that give up core.
2374- __sync_and_and_fetch(&m_test_flags, ~test_flag_do_work);
2375- }
2376-
2377- if ((m_test_flags & test_flag_post_poke)) {
2378- }
2379-}
2380-
2381-bool
2382-wait_for_true(std::function<bool ()> test_function) {
2383- int i = 100;
2384-
2385- do {
2386- if (test_function())
2387- return true;
2388-
2389- usleep(10 * 1000);
2390- } while (--i);
2391-
2392- return false;
2393-}
2394-
2395-void
2396-utils_thread_base_test::setUp() {
2397-}
2398-
2399-void
2400-utils_thread_base_test::tearDown() {
2401- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2402- torrent::thread_base::release_global_lock();
2403-}
2404-
2405-void
2406-utils_thread_base_test::test_basic() {
2407- thread_test* thread = new thread_test;
2408-
2409- CPPUNIT_ASSERT(thread->flags() == 0);
2410-
2411- CPPUNIT_ASSERT(!thread->is_main_polling());
2412- CPPUNIT_ASSERT(!thread->is_active());
2413- CPPUNIT_ASSERT(thread->global_queue_size() == 0);
2414- CPPUNIT_ASSERT(thread->poll() == NULL);
2415-
2416- // Check active...
2417-}
2418-
2419-void
2420-utils_thread_base_test::test_lifecycle() {
2421- thread_test* thread = new thread_test;
2422-
2423- CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_UNKNOWN);
2424- CPPUNIT_ASSERT(thread->test_state() == thread_test::TEST_NONE);
2425-
2426- thread->init_thread();
2427- CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_INITIALIZED);
2428- CPPUNIT_ASSERT(thread->is_initialized());
2429- CPPUNIT_ASSERT(thread->test_state() == thread_test::TEST_PRE_START);
2430-
2431- thread->set_pre_stop();
2432- CPPUNIT_ASSERT(!wait_for_true(std::bind(&thread_test::is_test_state, thread, thread_test::TEST_PRE_STOP)));
2433-
2434- thread->start_thread();
2435- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_ACTIVE)));
2436- CPPUNIT_ASSERT(thread->is_active());
2437- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_test_state, thread, thread_test::TEST_PRE_STOP)));
2438-
2439- thread->stop_thread();
2440- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
2441- CPPUNIT_ASSERT(thread->is_inactive());
2442-
2443- delete thread;
2444-}
2445-
2446-void
2447-utils_thread_base_test::test_global_lock_basic() {
2448- thread_test* thread = new thread_test;
2449-
2450- thread->init_thread();
2451- thread->start_thread();
2452-
2453- CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
2454-
2455- // Acquire main thread...
2456- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2457- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2458-
2459- torrent::thread_base::release_global_lock();
2460- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2461- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2462-
2463- torrent::thread_base::release_global_lock();
2464- torrent::thread_base::acquire_global_lock();
2465- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2466-
2467- thread->set_acquire_global();
2468- CPPUNIT_ASSERT(!wait_for_true(std::bind(&thread_test::is_test_flags, thread, thread_test::test_flag_has_global)));
2469-
2470- torrent::thread_base::release_global_lock();
2471- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_test_flags, thread, thread_test::test_flag_has_global)));
2472-
2473- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2474- torrent::thread_base::release_global_lock();
2475- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2476-
2477- // Test waive (loop).
2478-
2479- CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
2480-
2481- torrent::thread_base::release_global_lock();
2482- thread->stop_thread();
2483- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
2484-
2485- delete thread;
2486-}
2487-
2488-void
2489-utils_thread_base_test::test_interrupt() {
2490- thread_test* thread = new thread_test;
2491- thread->set_test_flag(thread_test::test_flag_long_timeout);
2492-
2493- thread->init_thread();
2494- thread->start_thread();
2495-
2496- // Vary the various timeouts.
2497-
2498- for (int i = 0; i < 100; i++) {
2499- thread->interrupt();
2500- usleep(0);
2501-
2502- thread->set_test_flag(thread_test::test_flag_do_work);
2503- thread->interrupt();
2504-
2505- // Wait for flag to clear.
2506- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_not_test_flags, thread, thread_test::test_flag_do_work)));
2507- }
2508-
2509- thread->stop_thread();
2510- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
2511-
2512- delete thread;
2513-}
2514-
2515-void
2516-utils_thread_base_test::test_stop() {
2517- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
2518- // torrent::thread_base::acquire_global_lock();
2519-
2520- for (int i = 0; i < 20; i++) {
2521- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
2522-
2523- thread_test* thread = new thread_test;
2524- thread->set_test_flag(thread_test::test_flag_do_work);
2525-
2526- thread->init_thread();
2527- thread->start_thread();
2528-
2529- thread->stop_thread_wait();
2530- CPPUNIT_ASSERT(thread->is_inactive());
2531-
2532- delete thread;
2533- }
2534-
2535- torrent::thread_base::release_global_lock();
2536-}
2537diff --git a/test/torrent/utils/thread_base_test.h b/test/torrent/utils/thread_base_test.h
2538deleted file mode 100644
2539index 22eb99dc..00000000
2540--- a/test/torrent/utils/thread_base_test.h
2541+++ /dev/null
2542@@ -1,86 +0,0 @@
2543-#include <cppunit/extensions/HelperMacros.h>
2544-
2545-#include "torrent/utils/thread_base.h"
2546-
2547-class utils_thread_base_test : public CppUnit::TestFixture {
2548- CPPUNIT_TEST_SUITE(utils_thread_base_test);
2549- CPPUNIT_TEST(test_basic);
2550- CPPUNIT_TEST(test_lifecycle);
2551-
2552- CPPUNIT_TEST(test_global_lock_basic);
2553- CPPUNIT_TEST(test_interrupt);
2554- CPPUNIT_TEST(test_stop);
2555- CPPUNIT_TEST_SUITE_END();
2556-
2557-public:
2558- void setUp();
2559- void tearDown();
2560-
2561- void test_basic();
2562- void test_lifecycle();
2563-
2564- void test_global_lock_basic();
2565- void test_interrupt();
2566- void test_interrupt_legacy();
2567- void test_stop();
2568-};
2569-
2570-struct thread_management_type {
2571- thread_management_type() { CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); }
2572- ~thread_management_type() { torrent::thread_base::release_global_lock(); }
2573-};
2574-
2575-#define SETUP_THREAD() \
2576- thread_management_type thread_management; \
2577- torrent::thread_disk* thread_disk = new torrent::thread_disk(); \
2578- thread_disk->init_thread();
2579-
2580-#define CLEANUP_THREAD() \
2581- CPPUNIT_ASSERT(wait_for_true(std::bind(&torrent::thread_base::is_inactive, thread_disk))); \
2582- delete thread_disk;
2583-
2584-bool wait_for_true(std::function<bool ()> test_function);
2585-
2586-class thread_test : public torrent::thread_base {
2587-public:
2588- enum test_state {
2589- TEST_NONE,
2590- TEST_PRE_START,
2591- TEST_PRE_STOP,
2592- TEST_STOP
2593- };
2594-
2595- static const int test_flag_pre_stop = 0x1;
2596- static const int test_flag_long_timeout = 0x2;
2597-
2598- static const int test_flag_acquire_global = 0x10;
2599- static const int test_flag_has_global = 0x20;
2600-
2601- static const int test_flag_do_work = 0x100;
2602- static const int test_flag_pre_poke = 0x200;
2603- static const int test_flag_post_poke = 0x400;
2604-
2605- thread_test();
2606-
2607- int test_state() const { return m_test_state; }
2608- bool is_state(int state) const { return m_state == state; }
2609- bool is_test_state(int state) const { return m_test_state == state; }
2610- bool is_test_flags(int flags) const { return (m_test_flags & flags) == flags; }
2611- bool is_not_test_flags(int flags) const { return !(m_test_flags & flags); }
2612-
2613- const char* name() const { return "test_thread"; }
2614-
2615- void init_thread();
2616-
2617- void set_pre_stop() { __sync_or_and_fetch(&m_test_flags, test_flag_pre_stop); }
2618- void set_acquire_global() { __sync_or_and_fetch(&m_test_flags, test_flag_acquire_global); }
2619-
2620- void set_test_flag(int flags) { __sync_or_and_fetch(&m_test_flags, flags); }
2621-
2622-private:
2623- void call_events();
2624- int64_t next_timeout_usec() { return (m_test_flags & test_flag_long_timeout) ? (10000 * 1000) : (100 * 1000); }
2625-
2626- int m_test_state lt_cacheline_aligned;
2627- int m_test_flags lt_cacheline_aligned;
2628-};
2629diff --git a/test/tracker/test_tracker_http.cc b/test/tracker/test_tracker_http.cc
2630new file mode 100644
2631index 00000000..399d00d5
2632--- /dev/null
2633+++ b/test/tracker/test_tracker_http.cc
2634@@ -0,0 +1,11 @@
2635+#include "config.h"
2636+
2637+#include "test_tracker_http.h"
2638+
2639+#include "tracker/tracker_http.h"
2640+
2641+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_tracker_http, "tracker");
2642+
2643+void
2644+test_tracker_http::test_basic() {
2645+}
2646diff --git a/test/tracker/test_tracker_http.h b/test/tracker/test_tracker_http.h
2647new file mode 100644
2648index 00000000..ab11a8f7
2649--- /dev/null
2650+++ b/test/tracker/test_tracker_http.h
2651@@ -0,0 +1,12 @@
2652+#include "helpers/test_fixture.h"
2653+
2654+#include "torrent/utils/thread_base.h"
2655+
2656+class test_tracker_http : public test_fixture {
2657+ CPPUNIT_TEST_SUITE(test_tracker_http);
2658+ CPPUNIT_TEST(test_basic);
2659+ CPPUNIT_TEST_SUITE_END();
2660+
2661+public:
2662+ void test_basic();
2663+};
2664diff --git a/test/tracker/tracker_http_test.cc b/test/tracker/tracker_http_test.cc
2665deleted file mode 100644
2666index deda4382..00000000
2667--- a/test/tracker/tracker_http_test.cc
2668+++ /dev/null
2669@@ -1,17 +0,0 @@
2670-#include "config.h"
2671-
2672-#include "tracker_http_test.h"
2673-
2674-#include "tracker/tracker_http.h"
2675-
2676-void
2677-tracker_http_test::setUp() {
2678-}
2679-
2680-void
2681-tracker_http_test::tearDown() {
2682-}
2683-
2684-void
2685-tracker_http_test::test_basic() {
2686-}
2687diff --git a/test/tracker/tracker_http_test.h b/test/tracker/tracker_http_test.h
2688deleted file mode 100644
2689index 11ff8246..00000000
2690--- a/test/tracker/tracker_http_test.h
2691+++ /dev/null
2692@@ -1,18 +0,0 @@
2693-#include <cppunit/extensions/HelperMacros.h>
2694-
2695-#include "tracker/tracker_http.h"
2696-
2697-class tracker_http_test : public CppUnit::TestFixture {
2698- CPPUNIT_TEST_SUITE(tracker_http_test);
2699- CPPUNIT_TEST(test_basic);
2700- CPPUNIT_TEST(test_scrape);
2701- CPPUNIT_TEST_SUITE_END();
2702-
2703-public:
2704- void setUp();
2705- void tearDown();
2706-
2707- void test_basic();
2708-
2709- void test_scrape();
2710-};
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch
new file mode 100644
index 0000000000..e860045a78
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch
@@ -0,0 +1,22 @@
1From 03e1c95987917bf98534e50fdd718a948540ffb2 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Thu, 25 Feb 2021 00:03:27 +0900
4Subject: [PATCH] Changes automake required files.
5
6---
7 autogen.sh | 2 +-
8 1 file changed, 1 insertion(+), 1 deletion(-)
9
10diff --git a/autogen.sh b/autogen.sh
11index 79afab8e..6def96dd 100755
12--- a/autogen.sh
13+++ b/autogen.sh
14@@ -36,7 +36,7 @@ echo automake...
15 exit 1
16 }
17
18-automake --add-missing --copy --gnu || exit 1
19+automake --add-missing --copy --foreign || exit 1
20
21 echo autoconf...
22 (autoconf --version) < /dev/null > /dev/null 2>&1 || {
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch
new file mode 100644
index 0000000000..0ff30731cb
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch
@@ -0,0 +1,48 @@
1From b4a3888bd891d804a83ae1cee623592725975895 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Sat, 27 Feb 2021 22:11:55 +0900
4Subject: [PATCH] Replaced custom execinfo autoconf test.
5
6---
7 configure.ac | 2 +-
8 scripts/rak_execinfo.m4 | 11 -----------
9 2 files changed, 1 insertion(+), 12 deletions(-)
10 delete mode 100644 scripts/rak_execinfo.m4
11
12diff --git a/configure.ac b/configure.ac
13index 88a46edd..197bbc94 100644
14--- a/configure.ac
15+++ b/configure.ac
16@@ -34,7 +34,6 @@ RAK_CHECK_CXXFLAGS
17 RAK_ENABLE_DEBUG
18 RAK_ENABLE_EXTRA_DEBUG
19 RAK_ENABLE_WERROR
20-RAK_DISABLE_BACKTRACE
21
22 RAK_CHECK_CXX11
23
24@@ -58,6 +57,7 @@ TORRENT_WITH_INOTIFY
25 CC_ATTRIBUTE_VISIBILITY
26
27 AX_CHECK_ZLIB
28+AX_EXECINFO
29 AX_PTHREAD
30
31 PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
32diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4
33deleted file mode 100644
34index c1d9b2f8..00000000
35--- a/scripts/rak_execinfo.m4
36+++ /dev/null
37@@ -1,11 +0,0 @@
38-AC_DEFUN([RAK_DISABLE_BACKTRACE], [
39- AC_ARG_ENABLE(backtrace,
40- AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]),
41- [
42- if test "$enableval" = "yes"; then
43- AX_EXECINFO
44- fi
45- ],[
46- AX_EXECINFO
47- ])
48-])
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch
new file mode 100644
index 0000000000..9d3c0fa23e
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch
@@ -0,0 +1,135 @@
1From e5ed6301e0d07adeaab10e9924a8c9a2e327cdc5 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Thu, 29 Apr 2021 19:33:04 +0900
4Subject: [PATCH] Added option to disable pthread_setname_np.
5
6---
7 configure.ac | 30 +++++++++++++++++++-----------
8 scripts/checks.m4 | 18 ++++++++++++++++++
9 src/torrent/utils/thread_base.cc | 16 ++++++++++++++--
10 3 files changed, 51 insertions(+), 13 deletions(-)
11
12diff --git a/configure.ac b/configure.ac
13index 197bbc94..73caf712 100644
14--- a/configure.ac
15+++ b/configure.ac
16@@ -24,9 +24,9 @@ AC_PROG_CXX
17 AC_SYS_LARGEFILE
18
19 AC_C_BIGENDIAN(
20- AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian),
21- AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian),
22- AC_MSG_ERROR([Could not determine endianness])
23+ AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian),
24+ AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian),
25+ AC_MSG_ERROR([Could not determine endianness])
26 )
27
28 RAK_CHECK_CFLAGS
29@@ -54,7 +54,15 @@ TORRENT_WITHOUT_STATVFS
30 TORRENT_WITHOUT_STATFS
31 TORRENT_WITH_INOTIFY
32
33-CC_ATTRIBUTE_VISIBILITY
34+AC_ARG_ENABLE(attribute-visibility,
35+ AC_HELP_STRING([--disable-attribute-visibility], [disable symbol visibility attribute [[default=enable]]]),
36+ [
37+ if test "$enableval" = "yes"; then
38+ CC_ATTRIBUTE_VISIBILITY
39+ fi
40+ ],[
41+ CC_ATTRIBUTE_VISIBILITY
42+ ])
43
44 AX_CHECK_ZLIB
45 AX_EXECINFO
46@@ -71,11 +79,11 @@ TORRENT_ARG_CYRUS_RC4
47
48 AC_CHECK_FUNCS(posix_memalign)
49
50-TORRENT_CHECK_MADVISE()
51-TORRENT_CHECK_CACHELINE()
52-TORRENT_CHECK_POPCOUNT()
53-TORRENT_CHECK_PTHREAD_SETNAME_NP()
54-TORRENT_MINCORE()
55+TORRENT_CHECK_MADVISE
56+TORRENT_CHECK_CACHELINE
57+TORRENT_CHECK_POPCOUNT
58+TORRENT_DISABLE_PTHREAD_SETNAME_NP
59+TORRENT_MINCORE
60
61 TORRENT_DISABLE_INSTRUMENTATION
62
63@@ -88,8 +96,8 @@ AC_SUBST(LIBTORRENT_CFLAGS)
64 AC_DEFINE(HAVE_CONFIG_H, 1, true if config.h was included)
65
66 CC_ATTRIBUTE_UNUSED(
67- AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
68- AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
69+ AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
70+ AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
71 )
72
73 AC_OUTPUT([
74diff --git a/scripts/checks.m4 b/scripts/checks.m4
75index 98ef17f8..915a5011 100644
76--- a/scripts/checks.m4
77+++ b/scripts/checks.m4
78@@ -490,3 +490,21 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
79 ])
80 ])
81 ])
82+
83+AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [
84+ AC_MSG_CHECKING([for pthread_setname_no])
85+
86+ AC_ARG_ENABLE(pthread-setname-np,
87+ AC_HELP_STRING([--disable-pthread-setname-np], [disable pthread_setname_np]),
88+ [
89+ if test "$enableval" = "no"; then
90+ AC_MSG_RESULT(disabled)
91+ else
92+ AC_MSG_RESULT(checking)
93+ TORRENT_CHECK_PTHREAD_SETNAME_NP
94+ fi
95+ ], [
96+ TORRENT_CHECK_PTHREAD_SETNAME_NP
97+ ]
98+ )
99+])
100diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc
101index 99d6355d..ec0619f3 100644
102--- a/src/torrent/utils/thread_base.cc
103+++ b/src/torrent/utils/thread_base.cc
104@@ -41,10 +41,16 @@ thread_base::~thread_base() {
105
106 void
107 thread_base::start_thread() {
108- if (m_poll == NULL)
109+ if (this == nullptr)
110+ throw internal_error("Called thread_base::start_thread on a nullptr.");
111+
112+ if (m_poll == nullptr)
113 throw internal_error("No poll object for thread defined.");
114
115- if (!is_initialized() || pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this))
116+ if (!is_initialized())
117+ throw internal_error("Called thread_base::start_thread on an uninitialized object.");
118+
119+ if (pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this))
120 throw internal_error("Failed to create thread.");
121 }
122
123@@ -82,6 +88,12 @@ thread_base::should_handle_sigusr1() {
124
125 void*
126 thread_base::event_loop(thread_base* thread) {
127+ if (thread == nullptr)
128+ throw internal_error("thread_base::event_loop called with a null pointer thread");
129+
130+ if (!thread->is_initialized())
131+ throw internal_error("thread_base::event_loop call on an uninitialized object");
132+
133 __sync_lock_test_and_set(&thread->m_state, STATE_ACTIVE);
134
135 #if defined(HAS_PTHREAD_SETNAME_NP_DARWIN)
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch
new file mode 100644
index 0000000000..5f48d76bfd
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch
@@ -0,0 +1,594 @@
1From f978e68f9d907e25207d0a7d247d2b10935e5d76 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Thu, 29 Apr 2021 19:34:35 +0900
4Subject: [PATCH] Improved backtrace error checking.
5
6---
7 src/download/download_main.cc | 36 -------------
8 src/download/download_main.h | 36 -------------
9 src/download/download_wrapper.cc | 43 ++--------------
10 src/torrent/data/download_data.h | 36 -------------
11 src/torrent/download/choke_queue.cc | 50 +++++-------------
12 src/torrent/download/resource_manager.cc | 53 +++++--------------
13 src/torrent/exceptions.cc | 65 +++++++-----------------
14 src/torrent/torrent.cc | 1 +
15 src/torrent/utils/extents.h | 36 -------------
16 src/torrent/utils/signal_bitfield.cc | 36 -------------
17 10 files changed, 48 insertions(+), 344 deletions(-)
18
19diff --git a/src/download/download_main.cc b/src/download/download_main.cc
20index 9a3f9df2..e075038a 100644
21--- a/src/download/download_main.cc
22+++ b/src/download/download_main.cc
23@@ -1,39 +1,3 @@
24-// libTorrent - BitTorrent library
25-// Copyright (C) 2005-2011, Jari Sundell
26-//
27-// This program is free software; you can redistribute it and/or modify
28-// it under the terms of the GNU General Public License as published by
29-// the Free Software Foundation; either version 2 of the License, or
30-// (at your option) any later version.
31-//
32-// This program is distributed in the hope that it will be useful,
33-// but WITHOUT ANY WARRANTY; without even the implied warranty of
34-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35-// GNU General Public License for more details.
36-//
37-// You should have received a copy of the GNU General Public License
38-// along with this program; if not, write to the Free Software
39-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
40-//
41-// In addition, as a special exception, the copyright holders give
42-// permission to link the code of portions of this program with the
43-// OpenSSL library under certain conditions as described in each
44-// individual source file, and distribute linked combinations
45-// including the two.
46-//
47-// You must obey the GNU General Public License in all respects for
48-// all of the code used other than OpenSSL. If you modify file(s)
49-// with this exception, you may extend this exception to your version
50-// of the file(s), but you are not obligated to do so. If you do not
51-// wish to do so, delete this exception statement from your version.
52-// If you delete this exception statement from all source files in the
53-// program, then also delete it here.
54-//
55-// Contact: Jari Sundell <jaris@ifi.uio.no>
56-//
57-// Skomakerveien 33
58-// 3185 Skoppum, NORWAY
59-
60 #include "config.h"
61
62 #include <cstring>
63diff --git a/src/download/download_main.h b/src/download/download_main.h
64index da3cf182..4783e863 100644
65--- a/src/download/download_main.h
66+++ b/src/download/download_main.h
67@@ -1,39 +1,3 @@
68-// libTorrent - BitTorrent library
69-// Copyright (C) 2005-2011, Jari Sundell
70-//
71-// This program is free software; you can redistribute it and/or modify
72-// it under the terms of the GNU General Public License as published by
73-// the Free Software Foundation; either version 2 of the License, or
74-// (at your option) any later version.
75-//
76-// This program is distributed in the hope that it will be useful,
77-// but WITHOUT ANY WARRANTY; without even the implied warranty of
78-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
79-// GNU General Public License for more details.
80-//
81-// You should have received a copy of the GNU General Public License
82-// along with this program; if not, write to the Free Software
83-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
84-//
85-// In addition, as a special exception, the copyright holders give
86-// permission to link the code of portions of this program with the
87-// OpenSSL library under certain conditions as described in each
88-// individual source file, and distribute linked combinations
89-// including the two.
90-//
91-// You must obey the GNU General Public License in all respects for
92-// all of the code used other than OpenSSL. If you modify file(s)
93-// with this exception, you may extend this exception to your version
94-// of the file(s), but you are not obligated to do so. If you do not
95-// wish to do so, delete this exception statement from your version.
96-// If you delete this exception statement from all source files in the
97-// program, then also delete it here.
98-//
99-// Contact: Jari Sundell <jaris@ifi.uio.no>
100-//
101-// Skomakerveien 33
102-// 3185 Skoppum, NORWAY
103-
104 #ifndef LIBTORRENT_DOWNLOAD_MAIN_H
105 #define LIBTORRENT_DOWNLOAD_MAIN_H
106
107diff --git a/src/download/download_wrapper.cc b/src/download/download_wrapper.cc
108index 59e81781..304bddce 100644
109--- a/src/download/download_wrapper.cc
110+++ b/src/download/download_wrapper.cc
111@@ -1,39 +1,3 @@
112-// libTorrent - BitTorrent library
113-// Copyright (C) 2005-2011, Jari Sundell
114-//
115-// This program is free software; you can redistribute it and/or modify
116-// it under the terms of the GNU General Public License as published by
117-// the Free Software Foundation; either version 2 of the License, or
118-// (at your option) any later version.
119-//
120-// This program is distributed in the hope that it will be useful,
121-// but WITHOUT ANY WARRANTY; without even the implied warranty of
122-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
123-// GNU General Public License for more details.
124-//
125-// You should have received a copy of the GNU General Public License
126-// along with this program; if not, write to the Free Software
127-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
128-//
129-// In addition, as a special exception, the copyright holders give
130-// permission to link the code of portions of this program with the
131-// OpenSSL library under certain conditions as described in each
132-// individual source file, and distribute linked combinations
133-// including the two.
134-//
135-// You must obey the GNU General Public License in all respects for
136-// all of the code used other than OpenSSL. If you modify file(s)
137-// with this exception, you may extend this exception to your version
138-// of the file(s), but you are not obligated to do so. If you do not
139-// wish to do so, delete this exception statement from your version.
140-// If you delete this exception statement from all source files in the
141-// program, then also delete it here.
142-//
143-// Contact: Jari Sundell <jaris@ifi.uio.no>
144-//
145-// Skomakerveien 33
146-// 3185 Skoppum, NORWAY
147-
148 #include "config.h"
149
150 #include <iterator>
151@@ -62,6 +26,8 @@
152
153 #include "download_wrapper.h"
154
155+#define LT_LOG_THIS(log_fmt, ...) \
156+ lt_log_print_info(LOG_TORRENT_INFO, this->info(), "download", log_fmt, __VA_ARGS__);
157 #define LT_LOG_STORAGE_ERRORS(log_fmt, ...) \
158 lt_log_print_info(LOG_PROTOCOL_STORAGE_ERRORS, this->info(), "storage_errors", log_fmt, __VA_ARGS__);
159
160@@ -325,8 +291,8 @@ DownloadWrapper::receive_tick(uint32_t ticks) {
161
162 void
163 DownloadWrapper::receive_update_priorities() {
164- if (m_main->chunk_selector()->empty())
165- return;
166+ LT_LOG_THIS("update priorities: chunks_selected:%" PRIu32 " wanted_chunks:%" PRIu32,
167+ m_main->chunk_selector()->size(), data()->wanted_chunks());
168
169 data()->mutable_high_priority()->clear();
170 data()->mutable_normal_priority()->clear();
171@@ -359,7 +325,6 @@ DownloadWrapper::receive_update_priorities() {
172 }
173
174 bool was_partial = data()->wanted_chunks() != 0;
175-
176 data()->update_wanted_chunks();
177
178 m_main->chunk_selector()->update_priorities();
179diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h
180index fc212047..c701cb2f 100644
181--- a/src/torrent/data/download_data.h
182+++ b/src/torrent/data/download_data.h
183@@ -1,39 +1,3 @@
184-// libTorrent - BitTorrent library
185-// Copyright (C) 2005-2011, Jari Sundell
186-//
187-// This program is free software; you can redistribute it and/or modify
188-// it under the terms of the GNU General Public License as published by
189-// the Free Software Foundation; either version 2 of the License, or
190-// (at your option) any later version.
191-//
192-// This program is distributed in the hope that it will be useful,
193-// but WITHOUT ANY WARRANTY; without even the implied warranty of
194-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
195-// GNU General Public License for more details.
196-//
197-// You should have received a copy of the GNU General Public License
198-// along with this program; if not, write to the Free Software
199-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
200-//
201-// In addition, as a special exception, the copyright holders give
202-// permission to link the code of portions of this program with the
203-// OpenSSL library under certain conditions as described in each
204-// individual source file, and distribute linked combinations
205-// including the two.
206-//
207-// You must obey the GNU General Public License in all respects for
208-// all of the code used other than OpenSSL. If you modify file(s)
209-// with this exception, you may extend this exception to your version
210-// of the file(s), but you are not obligated to do so. If you do not
211-// wish to do so, delete this exception statement from your version.
212-// If you delete this exception statement from all source files in the
213-// program, then also delete it here.
214-//
215-// Contact: Jari Sundell <jaris@ifi.uio.no>
216-//
217-// Skomakerveien 33
218-// 3185 Skoppum, NORWAY
219-
220 #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H
221 #define LIBTORRENT_DATA_DOWNLOAD_DATA_H
222
223diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc
224index 7c00b686..edf47795 100644
225--- a/src/torrent/download/choke_queue.cc
226+++ b/src/torrent/download/choke_queue.cc
227@@ -1,39 +1,3 @@
228-// libTorrent - BitTorrent library
229-// Copyright (C) 2005-2011, Jari Sundell
230-//
231-// This program is free software; you can redistribute it and/or modify
232-// it under the terms of the GNU General Public License as published by
233-// the Free Software Foundation; either version 2 of the License, or
234-// (at your option) any later version.
235-//
236-// This program is distributed in the hope that it will be useful,
237-// but WITHOUT ANY WARRANTY; without even the implied warranty of
238-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
239-// GNU General Public License for more details.
240-//
241-// You should have received a copy of the GNU General Public License
242-// along with this program; if not, write to the Free Software
243-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
244-//
245-// In addition, as a special exception, the copyright holders give
246-// permission to link the code of portions of this program with the
247-// OpenSSL library under certain conditions as described in each
248-// individual source file, and distribute linked combinations
249-// including the two.
250-//
251-// You must obey the GNU General Public License in all respects for
252-// all of the code used other than OpenSSL. If you modify file(s)
253-// with this exception, you may extend this exception to your version
254-// of the file(s), but you are not obligated to do so. If you do not
255-// wish to do so, delete this exception statement from your version.
256-// If you delete this exception statement from all source files in the
257-// program, then also delete it here.
258-//
259-// Contact: Jari Sundell <jaris@ifi.uio.no>
260-//
261-// Skomakerveien 33
262-// 3185 Skoppum, NORWAY
263-
264 #include "config.h"
265
266 #include <algorithm>
267@@ -50,6 +14,10 @@
268
269 #include "choke_queue.h"
270
271+// TODO: Add a different logging category.
272+#define LT_LOG_THIS(log_fmt, ...) \
273+ lt_log_print_subsystem(LOG_TORRENT_INFO, "choke_queue", log_fmt, __VA_ARGS__);
274+
275 namespace torrent {
276
277 struct choke_manager_less {
278@@ -193,6 +161,9 @@ choke_queue::rebuild_containers(container_type* queued, container_type* unchoked
279
280 void
281 choke_queue::balance() {
282+ LT_LOG_THIS("balancing queue: heuristics:%i currently_unchoked:%" PRIu32 " max_unchoked:%" PRIu32,
283+ m_heuristics, m_currently_unchoked, m_maxUnchoked)
284+
285 // Return if no balancing is needed. Don't return if is_unlimited()
286 // as we might have just changed the value and have interested that
287 // can be unchoked.
288@@ -216,6 +187,9 @@ choke_queue::balance() {
289
290 // If we have more unchoked than max global slots allow for,
291 // 'can_unchoke' will be negative.
292+ //
293+ // Throws std::bad_function_call if 'set_slot_can_unchoke' is not
294+ // set.
295 int can_unchoke = m_slotCanUnchoke();
296 int max_unchoked = std::min(m_maxUnchoked, (uint32_t)(1 << 20));
297
298@@ -240,8 +214,8 @@ choke_queue::balance() {
299 if (result != 0)
300 m_slotUnchoke(result);
301
302- lt_log_print(LOG_PEER_DEBUG, "Called balance; adjust:%i can_unchoke:%i queued:%u unchoked:%u result:%i.",
303- adjust, can_unchoke, (unsigned)queued.size(), (unsigned)unchoked.size(), result);
304+ LT_LOG_THIS("balanced queue: adjust:%i can_unchoke:%i queued:%" PRIu32 " unchoked:%" PRIu32 " result:%i",
305+ adjust, can_unchoke, queued.size(), unchoked.size(), result);
306 }
307
308 void
309diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc
310index 51434c91..8ca7b02e 100644
311--- a/src/torrent/download/resource_manager.cc
312+++ b/src/torrent/download/resource_manager.cc
313@@ -1,39 +1,3 @@
314-// libTorrent - BitTorrent library
315-// Copyright (C) 2005-2011, Jari Sundell
316-//
317-// This program is free software; you can redistribute it and/or modify
318-// it under the terms of the GNU General Public License as published by
319-// the Free Software Foundation; either version 2 of the License, or
320-// (at your option) any later version.
321-//
322-// This program is distributed in the hope that it will be useful,
323-// but WITHOUT ANY WARRANTY; without even the implied warranty of
324-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
325-// GNU General Public License for more details.
326-//
327-// You should have received a copy of the GNU General Public License
328-// along with this program; if not, write to the Free Software
329-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
330-//
331-// In addition, as a special exception, the copyright holders give
332-// permission to link the code of portions of this program with the
333-// OpenSSL library under certain conditions as described in each
334-// individual source file, and distribute linked combinations
335-// including the two.
336-//
337-// You must obey the GNU General Public License in all respects for
338-// all of the code used other than OpenSSL. If you modify file(s)
339-// with this exception, you may extend this exception to your version
340-// of the file(s), but you are not obligated to do so. If you do not
341-// wish to do so, delete this exception statement from your version.
342-// If you delete this exception statement from all source files in the
343-// program, then also delete it here.
344-//
345-// Contact: Jari Sundell <jaris@ifi.uio.no>
346-//
347-// Skomakerveien 33
348-// 3185 Skoppum, NORWAY
349-
350 #include "config.h"
351
352 #include <algorithm>
353@@ -51,6 +15,11 @@
354 #include "choke_queue.h"
355 #include "resource_manager.h"
356
357+#define LT_LOG_THIS(log_fmt, ...) \
358+ lt_log_print_subsystem(LOG_TORRENT_INFO, "resource_manager", log_fmt, __VA_ARGS__);
359+#define LT_LOG_ITR(log_fmt, ...) \
360+ lt_log_print_info(LOG_TORRENT_INFO, itr->download()->info(), "resource_manager", log_fmt, __VA_ARGS__);
361+
362 namespace torrent {
363
364 const Rate* resource_manager_entry::up_rate() const { return m_download->info()->up_rate(); }
365@@ -226,6 +195,8 @@ ResourceManager::group_index_of(const std::string& name) {
366
367 void
368 ResourceManager::set_priority(iterator itr, uint16_t pri) {
369+ LT_LOG_ITR("set priority: %" PRIu16, 0)
370+
371 itr->set_priority(pri);
372 }
373
374@@ -283,7 +254,7 @@ ResourceManager::set_max_download_unchoked(unsigned int m) {
375 // possibly multiple calls of this function.
376 void
377 ResourceManager::receive_upload_unchoke(int num) {
378- lt_log_print(LOG_PEER_INFO, "Upload unchoked slots adjust; currently:%u adjust:%i", m_currentlyUploadUnchoked, num);
379+ LT_LOG_THIS("adjusting upload unchoked slots; current:%u adjusted:%i", m_currentlyUploadUnchoked, num);
380
381 if ((int)m_currentlyUploadUnchoked + num < 0)
382 throw internal_error("ResourceManager::receive_upload_unchoke(...) received an invalid value.");
383@@ -293,7 +264,7 @@ ResourceManager::receive_upload_unchoke(int num) {
384
385 void
386 ResourceManager::receive_download_unchoke(int num) {
387- lt_log_print(LOG_PEER_INFO, "Download unchoked slots adjust; currently:%u adjust:%i", m_currentlyDownloadUnchoked, num);
388+ LT_LOG_THIS("adjusting download unchoked slots; current:%u adjusted:%i", m_currentlyDownloadUnchoked, num);
389
390 if ((int)m_currentlyDownloadUnchoked + num < 0)
391 throw internal_error("ResourceManager::receive_download_unchoke(...) received an invalid value.");
392@@ -387,12 +358,14 @@ ResourceManager::balance_unchoked(unsigned int weight, unsigned int max_unchoked
393 std::sort(group_first, group_last, std::bind(std::less<uint32_t>(),
394 std::bind(&choke_group::up_requested, std::placeholders::_1),
395 std::bind(&choke_group::up_requested, std::placeholders::_2)));
396- lt_log_print(LOG_PEER_DEBUG, "Upload unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked);
397+
398+ LT_LOG_THIS("balancing upload unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked);
399 } else {
400 std::sort(group_first, group_last, std::bind(std::less<uint32_t>(),
401 std::bind(&choke_group::down_requested, std::placeholders::_1),
402 std::bind(&choke_group::down_requested, std::placeholders::_2)));
403- lt_log_print(LOG_PEER_DEBUG, "Download unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked);
404+
405+ LT_LOG_THIS("balancing download unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked);
406 }
407
408 while (group_first != group_last) {
409diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc
410index f834f9fa..7375ed8e 100644
411--- a/src/torrent/exceptions.cc
412+++ b/src/torrent/exceptions.cc
413@@ -1,39 +1,3 @@
414-// libTorrent - BitTorrent library
415-// Copyright (C) 2005-2011, Jari Sundell
416-//
417-// This program is free software; you can redistribute it and/or modify
418-// it under the terms of the GNU General Public License as published by
419-// the Free Software Foundation; either version 2 of the License, or
420-// (at your option) any later version.
421-//
422-// This program is distributed in the hope that it will be useful,
423-// but WITHOUT ANY WARRANTY; without even the implied warranty of
424-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
425-// GNU General Public License for more details.
426-//
427-// You should have received a copy of the GNU General Public License
428-// along with this program; if not, write to the Free Software
429-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
430-//
431-// In addition, as a special exception, the copyright holders give
432-// permission to link the code of portions of this program with the
433-// OpenSSL library under certain conditions as described in each
434-// individual source file, and distribute linked combinations
435-// including the two.
436-//
437-// You must obey the GNU General Public License in all respects for
438-// all of the code used other than OpenSSL. If you modify file(s)
439-// with this exception, you may extend this exception to your version
440-// of the file(s), but you are not obligated to do so. If you do not
441-// wish to do so, delete this exception statement from your version.
442-// If you delete this exception statement from all source files in the
443-// program, then also delete it here.
444-//
445-// Contact: Jari Sundell <jaris@ifi.uio.no>
446-//
447-// Skomakerveien 33
448-// 3185 Skoppum, NORWAY
449-
450 #include "config.h"
451
452 #include <cerrno>
453@@ -73,23 +37,30 @@ void
454 internal_error::initialize(const std::string& msg) {
455 m_msg = msg;
456
457- std::stringstream output;
458-
459 #ifdef HAVE_BACKTRACE
460- void* stackPtrs[20];
461+ void* stack_ptrs[20];
462+ int stack_size = ::backtrace(stack_ptrs, 20);
463+ char** stack_symbol_names = ::backtrace_symbols(stack_ptrs, stack_size);
464
465- // Print the stack and exit.
466- int stackSize = ::backtrace(stackPtrs, 20);
467- char** stackStrings = backtrace_symbols(stackPtrs, stackSize);
468+ if (stack_symbol_names == nullptr) {
469+ m_backtrace = "backtrace_symbols failed";
470+ return;
471+ }
472
473- for (int i = 0; i < stackSize; ++i)
474- output << stackStrings[i] << std::endl;
475+ std::stringstream output;
476
477-#else
478- output << "Stack dump not enabled." << std::endl;
479-#endif
480+ for (int i = 0; i < stack_size; ++i) {
481+ if (stack_symbol_names[i] != nullptr && stack_symbol_names[i] > (void*)0x1000)
482+ output << stack_symbol_names[i] << std::endl;
483+ else
484+ output << "stack_symbol: nullptr" << std::endl;
485+ }
486
487 m_backtrace = output.str();
488+
489+#else
490+ m_backtrace = "stack dump not enabled";
491+#endif
492 }
493
494 }
495diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc
496index fb70d247..67de4387 100644
497--- a/src/torrent/torrent.cc
498+++ b/src/torrent/torrent.cc
499@@ -203,6 +203,7 @@ download_priority(Download d) {
500 return itr->priority();
501 }
502
503+// TODO: Remove this.
504 void
505 download_set_priority(Download d, uint32_t pri) {
506 ResourceManager::iterator itr = manager->resource_manager()->find(d.ptr()->main());
507diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h
508index c2b887b1..64605d4a 100644
509--- a/src/torrent/utils/extents.h
510+++ b/src/torrent/utils/extents.h
511@@ -1,39 +1,3 @@
512-// libTorrent - BitTorrent library
513-// Copyright (C) 2005-2011, Jari Sundell
514-//
515-// This program is free software; you can redistribute it and/or modify
516-// it under the terms of the GNU General Public License as published by
517-// the Free Software Foundation; either version 2 of the License, or
518-// (at your option) any later version.
519-//
520-// This program is distributed in the hope that it will be useful,
521-// but WITHOUT ANY WARRANTY; without even the implied warranty of
522-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
523-// GNU General Public License for more details.
524-//
525-// You should have received a copy of the GNU General Public License
526-// along with this program; if not, write to the Free Software
527-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
528-//
529-// In addition, as a special exception, the copyright holders give
530-// permission to link the code of portions of this program with the
531-// OpenSSL library under certain conditions as described in each
532-// individual source file, and distribute linked combinations
533-// including the two.
534-//
535-// You must obey the GNU General Public License in all respects for
536-// all of the code used other than OpenSSL. If you modify file(s)
537-// with this exception, you may extend this exception to your version
538-// of the file(s), but you are not obligated to do so. If you do not
539-// wish to do so, delete this exception statement from your version.
540-// If you delete this exception statement from all source files in the
541-// program, then also delete it here.
542-//
543-// Contact: Jari Sundell <jaris@ifi.uio.no>
544-//
545-// Skomakerveien 33
546-// 3185 Skoppum, NORWAY
547-
548 #ifndef LIBTORRENT_UTILS_EXTENTS_H
549 #define LIBTORRENT_UTILS_EXTENTS_H
550
551diff --git a/src/torrent/utils/signal_bitfield.cc b/src/torrent/utils/signal_bitfield.cc
552index 82f81e7c..dfc3d1fe 100644
553--- a/src/torrent/utils/signal_bitfield.cc
554+++ b/src/torrent/utils/signal_bitfield.cc
555@@ -1,39 +1,3 @@
556-// libTorrent - BitTorrent library
557-// Copyright (C) 2005-2011, Jari Sundell
558-//
559-// This program is free software; you can redistribute it and/or modify
560-// it under the terms of the GNU General Public License as published by
561-// the Free Software Foundation; either version 2 of the License, or
562-// (at your option) any later version.
563-//
564-// This program is distributed in the hope that it will be useful,
565-// but WITHOUT ANY WARRANTY; without even the implied warranty of
566-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
567-// GNU General Public License for more details.
568-//
569-// You should have received a copy of the GNU General Public License
570-// along with this program; if not, write to the Free Software
571-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
572-//
573-// In addition, as a special exception, the copyright holders give
574-// permission to link the code of portions of this program with the
575-// OpenSSL library under certain conditions as described in each
576-// individual source file, and distribute linked combinations
577-// including the two.
578-//
579-// You must obey the GNU General Public License in all respects for
580-// all of the code used other than OpenSSL. If you modify file(s)
581-// with this exception, you may extend this exception to your version
582-// of the file(s), but you are not obligated to do so. If you do not
583-// wish to do so, delete this exception statement from your version.
584-// If you delete this exception statement from all source files in the
585-// program, then also delete it here.
586-//
587-// Contact: Jari Sundell <jaris@ifi.uio.no>
588-//
589-// Skomakerveien 33
590-// 3185 Skoppum, NORWAY
591-
592 #include "config.h"
593
594 #include "torrent/exceptions.h"
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch
new file mode 100644
index 0000000000..8937e869fa
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch
@@ -0,0 +1,199 @@
1From cabc557fdf6f12fee7029081de2cf5de88464c21 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Thu, 29 Apr 2021 21:27:50 +0900
4Subject: [PATCH] Fixed issue with multiple connections from NAT not working.
5
6---
7 src/protocol/handshake.cc | 36 -------------------
8 src/torrent/peer/peer_list.cc | 68 +++++++++++------------------------
9 src/torrent/peer/peer_list.h | 36 -------------------
10 3 files changed, 20 insertions(+), 120 deletions(-)
11
12diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc
13index 1b877c7a..d6f48e59 100644
14--- a/src/protocol/handshake.cc
15+++ b/src/protocol/handshake.cc
16@@ -1,39 +1,3 @@
17-// libTorrent - BitTorrent library
18-// Copyright (C) 2005-2011, Jari Sundell
19-//
20-// This program is free software; you can redistribute it and/or modify
21-// it under the terms of the GNU General Public License as published by
22-// the Free Software Foundation; either version 2 of the License, or
23-// (at your option) any later version.
24-//
25-// This program is distributed in the hope that it will be useful,
26-// but WITHOUT ANY WARRANTY; without even the implied warranty of
27-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28-// GNU General Public License for more details.
29-//
30-// You should have received a copy of the GNU General Public License
31-// along with this program; if not, write to the Free Software
32-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33-//
34-// In addition, as a special exception, the copyright holders give
35-// permission to link the code of portions of this program with the
36-// OpenSSL library under certain conditions as described in each
37-// individual source file, and distribute linked combinations
38-// including the two.
39-//
40-// You must obey the GNU General Public License in all respects for
41-// all of the code used other than OpenSSL. If you modify file(s)
42-// with this exception, you may extend this exception to your version
43-// of the file(s), but you are not obligated to do so. If you do not
44-// wish to do so, delete this exception statement from your version.
45-// If you delete this exception statement from all source files in the
46-// program, then also delete it here.
47-//
48-// Contact: Jari Sundell <jaris@ifi.uio.no>
49-//
50-// Skomakerveien 33
51-// 3185 Skoppum, NORWAY
52-
53 #include "config.h"
54
55 #include <stdio.h>
56diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc
57index 080a7f13..6ce630f7 100644
58--- a/src/torrent/peer/peer_list.cc
59+++ b/src/torrent/peer/peer_list.cc
60@@ -1,39 +1,3 @@
61-// libTorrent - BitTorrent library
62-// Copyright (C) 2005-2011, Jari Sundell
63-//
64-// This program is free software; you can redistribute it and/or modify
65-// it under the terms of the GNU General Public License as published by
66-// the Free Software Foundation; either version 2 of the License, or
67-// (at your option) any later version.
68-//
69-// This program is distributed in the hope that it will be useful,
70-// but WITHOUT ANY WARRANTY; without even the implied warranty of
71-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
72-// GNU General Public License for more details.
73-//
74-// You should have received a copy of the GNU General Public License
75-// along with this program; if not, write to the Free Software
76-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
77-//
78-// In addition, as a special exception, the copyright holders give
79-// permission to link the code of portions of this program with the
80-// OpenSSL library under certain conditions as described in each
81-// individual source file, and distribute linked combinations
82-// including the two.
83-//
84-// You must obey the GNU General Public License in all respects for
85-// all of the code used other than OpenSSL. If you modify file(s)
86-// with this exception, you may extend this exception to your version
87-// of the file(s), but you are not obligated to do so. If you do not
88-// wish to do so, delete this exception statement from your version.
89-// If you delete this exception statement from all source files in the
90-// program, then also delete it here.
91-//
92-// Contact: Jari Sundell <jaris@ifi.uio.no>
93-//
94-// Skomakerveien 33
95-// 3185 Skoppum, NORWAY
96-
97 #include "config.h"
98
99 #include <algorithm>
100@@ -262,8 +226,11 @@ PeerList::available_list_size() const {
101 return m_available_list->size();
102 }
103
104+// TODO: Rename connecting:
105 PeerInfo*
106 PeerList::connected(const sockaddr* sa, int flags) {
107+ // TODO: Rewrite to use new socket address api after fixing bug.
108+
109 const rak::socket_address* address = rak::socket_address::cast_from(sa);
110 socket_address_key sock_key = socket_address_key::from_sockaddr(sa);
111
112@@ -281,13 +248,7 @@ PeerList::connected(const sockaddr* sa, int flags) {
113 // We should also remove any PeerInfo objects already for this
114 // address.
115 if ((filter_value & PeerInfo::flag_unwanted)) {
116- char ipv4_str[INET_ADDRSTRLEN];
117- uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr);
118-
119- inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN);
120-
121- lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str);
122-
123+ LT_LOG_EVENTS("connecting peer rejected, flagged as unwanted: " LT_LOG_SA_FMT, address->address_str().c_str(), address->port());
124 return NULL;
125 }
126
127@@ -313,12 +274,23 @@ PeerList::connected(const sockaddr* sa, int flags) {
128 //
129 // This also ensure we can connect to peers running on the same
130 // host as the tracker.
131- if (flags & connect_keep_handshakes &&
132- range.first->second->is_handshake() &&
133- rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port())
134- m_available_list->buffer()->push_back(*address);
135+ // if (flags & connect_keep_handshakes &&
136+ // range.first->second->is_handshake() &&
137+ // rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port())
138+ // m_available_list->buffer()->push_back(*address);
139
140- return NULL;
141+ LT_LOG_EVENTS("connecting peer rejected, already connected (buggy, fixme): " LT_LOG_SA_FMT, address->address_str().c_str(), address->port());
142+
143+ // TODO: Verify this works properly, possibly add a check/flag
144+ // that allows the handshake manager to notify peer list if the
145+ // incoming connection was a duplicate peer hash.
146+
147+ //return NULL;
148+
149+ peerInfo = new PeerInfo(sa);
150+ peerInfo->set_flags(filter_value & PeerInfo::mask_ip_table);
151+
152+ base_type::insert(range.second, value_type(sock_key, peerInfo));
153 }
154
155 if (flags & connect_filter_recent &&
156diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h
157index 4c2f707d..a9d31a54 100644
158--- a/src/torrent/peer/peer_list.h
159+++ b/src/torrent/peer/peer_list.h
160@@ -1,39 +1,3 @@
161-// libTorrent - BitTorrent library
162-// Copyright (C) 2005-2011, Jari Sundell
163-//
164-// This program is free software; you can redistribute it and/or modify
165-// it under the terms of the GNU General Public License as published by
166-// the Free Software Foundation; either version 2 of the License, or
167-// (at your option) any later version.
168-//
169-// This program is distributed in the hope that it will be useful,
170-// but WITHOUT ANY WARRANTY; without even the implied warranty of
171-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
172-// GNU General Public License for more details.
173-//
174-// You should have received a copy of the GNU General Public License
175-// along with this program; if not, write to the Free Software
176-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
177-//
178-// In addition, as a special exception, the copyright holders give
179-// permission to link the code of portions of this program with the
180-// OpenSSL library under certain conditions as described in each
181-// individual source file, and distribute linked combinations
182-// including the two.
183-//
184-// You must obey the GNU General Public License in all respects for
185-// all of the code used other than OpenSSL. If you modify file(s)
186-// with this exception, you may extend this exception to your version
187-// of the file(s), but you are not obligated to do so. If you do not
188-// wish to do so, delete this exception statement from your version.
189-// If you delete this exception statement from all source files in the
190-// program, then also delete it here.
191-//
192-// Contact: Jari Sundell <jaris@ifi.uio.no>
193-//
194-// Skomakerveien 33
195-// 3185 Skoppum, NORWAY
196-
197 #ifndef LIBTORRENT_PEER_LIST_H
198 #define LIBTORRENT_PEER_LIST_H
199
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch
new file mode 100644
index 0000000000..a631b8de94
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch
@@ -0,0 +1,32 @@
1From 532d3e54b3f012dc81530ebb80ded8b26434fdd9 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Wed, 16 Jun 2021 23:28:28 +0900
4Subject: [PATCH] Added '--disable-execinfo' option to configure.
5
6---
7 configure.ac | 11 ++++++++++-
8 1 file changed, 10 insertions(+), 1 deletion(-)
9
10diff --git a/configure.ac b/configure.ac
11index 73caf712..a4f051e4 100644
12--- a/configure.ac
13+++ b/configure.ac
14@@ -64,8 +64,17 @@ AC_ARG_ENABLE(attribute-visibility,
15 CC_ATTRIBUTE_VISIBILITY
16 ])
17
18+AC_ARG_ENABLE(execinfo,
19+ AC_HELP_STRING([--disable-execinfo], [disable libexecinfo [[default=enable]]]),
20+ [
21+ if test "$enableval" = "yes"; then
22+ AX_EXECINFO
23+ fi
24+ ],[
25+ AX_EXECINFO
26+ ])
27+
28 AX_CHECK_ZLIB
29-AX_EXECINFO
30 AX_PTHREAD
31
32 PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch
new file mode 100644
index 0000000000..196d2f6aff
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch
@@ -0,0 +1,457 @@
1From 92781533fc4afab67447e8e6d47a649383179c44 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Sun, 20 Jun 2021 18:10:52 +0900
4Subject: [PATCH] Detect ip address.
5
6---
7 src/net/local_addr.cc | 6 +-
8 src/torrent/Makefile.am | 5 +-
9 src/torrent/net/fd.cc | 3 +
10 src/torrent/net/fd.h | 14 ++--
11 src/torrent/net/socket_address.cc | 2 +-
12 src/torrent/net/socket_address.h | 2 +-
13 src/torrent/net/utils.cc | 104 ++++++++++++++++++++++++
14 src/torrent/net/utils.h | 9 ++
15 src/tracker/tracker_http.cc | 104 ++++++++----------------
16 test/helpers/network.h | 2 +
17 test/torrent/net/test_fd.cc | 9 ++
18 test/torrent/net/test_socket_address.cc | 2 +-
19 12 files changed, 181 insertions(+), 81 deletions(-)
20 create mode 100755 src/torrent/net/utils.cc
21 create mode 100755 src/torrent/net/utils.h
22
23diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc
24index 24413265..0c7116cb 100644
25--- a/src/net/local_addr.cc
26+++ b/src/net/local_addr.cc
27@@ -34,6 +34,8 @@
28 // Skomakerveien 33
29 // 3185 Skoppum, NORWAY
30
31+// TODO: Remove.
32+
33 #include "config.h"
34
35 #include <stdio.h>
36@@ -241,7 +243,7 @@ bool get_local_address(sa_family_t family, rak::socket_address *address) {
37 int plen = IFA_PAYLOAD(nlmsg);
38 for (const rtattr *rta = IFA_RTA(ifa);
39 RTA_OK(rta, plen);
40- rta = RTA_NEXT(rta, plen)) {
41+ rta = RTA_NEXT(rta, plen)) {
42 if (rta->rta_type != IFA_LOCAL &&
43 rta->rta_type != IFA_ADDRESS) {
44 continue;
45@@ -303,7 +305,7 @@ get_local_address(sa_family_t family, rak::socket_address *address) {
46 dummy_dest.set_address_c_str("4.0.0.0");
47 break;
48 case rak::socket_address::af_inet6:
49- dummy_dest.set_address_c_str("2001:700::");
50+ dummy_dest.set_address_c_str("2001:1::");
51 break;
52 default:
53 throw internal_error("Unknown address family");
54diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am
55index 30157b95..5de7e8ae 100644
56--- a/src/torrent/Makefile.am
57+++ b/src/torrent/Makefile.am
58@@ -46,6 +46,8 @@ libtorrent_torrent_la_SOURCES = \
59 net/socket_event.cc \
60 net/socket_event.h \
61 net/types.h \
62+ net/utils.cc \
63+ net/utils.h \
64 \
65 peer/choke_status.h \
66 peer/client_info.cc \
67@@ -167,7 +169,8 @@ libtorrent_torrent_net_include_HEADERS = \
68 net/socket_address.h \
69 net/socket_address_key.h \
70 net/socket_event.h \
71- net/types.h
72+ net/types.h \
73+ net/utils.h
74
75 libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer
76 libtorrent_torrent_peer_include_HEADERS = \
77diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc
78index 07c91779..6d228181 100644
79--- a/src/torrent/net/fd.cc
80+++ b/src/torrent/net/fd.cc
81@@ -64,6 +64,9 @@ fd_open(fd_flags flags) {
82 if ((flags & fd_flag_stream)) {
83 domain = SOCK_STREAM;
84 protocol = IPPROTO_TCP;
85+ } else if ((flags & fd_flag_datagram)) {
86+ domain = SOCK_DGRAM;
87+ protocol = IPPROTO_UDP;
88 } else {
89 LT_LOG_FLAG("fd_open missing socket type");
90 errno = EINVAL;
91diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h
92index a7094646..6ab3302d 100644
93--- a/src/torrent/net/fd.h
94+++ b/src/torrent/net/fd.h
95@@ -9,11 +9,12 @@ namespace torrent {
96
97 enum fd_flags : int {
98 fd_flag_stream = 0x1,
99- fd_flag_nonblock = 0x10,
100- fd_flag_reuse_address = 0x20,
101- fd_flag_v4only = 0x40,
102- fd_flag_v6only = 0x80,
103- fd_flag_all = 0xff,
104+ fd_flag_datagram = 0x10,
105+ fd_flag_nonblock = 0x20,
106+ fd_flag_reuse_address = 0x40,
107+ fd_flag_v4only = 0x80,
108+ fd_flag_v6only = 0x100,
109+ fd_flag_all = 0x1ff,
110 };
111
112 constexpr bool fd_valid_flags(fd_flags flags);
113@@ -53,7 +54,8 @@ operator |=(fd_flags& lhs, fd_flags rhs) {
114 constexpr bool
115 fd_valid_flags(fd_flags flags) {
116 return
117- (flags & fd_flag_stream) &&
118+ ((flags & fd_flag_stream) || (flags & fd_flag_datagram)) &&
119+ !((flags & fd_flag_stream) && (flags & fd_flag_datagram)) &&
120 !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) &&
121 !(flags & ~(fd_flag_all));
122 }
123diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc
124index c36ba0ae..078bee25 100644
125--- a/src/torrent/net/socket_address.cc
126+++ b/src/torrent/net/socket_address.cc
127@@ -135,7 +135,7 @@ sa_unique_ptr
128 sa_make_unspec() {
129 sa_unique_ptr sa(new sockaddr);
130
131- std::memset(sa.get(), 0, sizeof(sa));
132+ std::memset(sa.get(), 0, sizeof(sockaddr));
133 sa.get()->sa_family = AF_UNSPEC;
134
135 return sa;
136diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h
137index f64aee68..b9586ca1 100644
138--- a/src/torrent/net/socket_address.h
139+++ b/src/torrent/net/socket_address.h
140@@ -102,8 +102,8 @@ bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_E
141
142 inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
143 inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
144-inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
145 inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
146+inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
147 inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
148 inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
149 inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); }
150diff --git a/src/torrent/net/utils.cc b/src/torrent/net/utils.cc
151new file mode 100755
152index 00000000..4cb85924
153--- /dev/null
154+++ b/src/torrent/net/utils.cc
155@@ -0,0 +1,104 @@
156+#import <torrent/net/utils.h>
157+
158+#import <cerrno>
159+#import <cstring>
160+#import <torrent/net/fd.h>
161+#import <torrent/net/socket_address.h>
162+#import <torrent/utils/log.h>
163+
164+#define LT_LOG_ERROR(log_fmt) \
165+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (errno:%i message:'%s')", \
166+ errno, std::strerror(errno));
167+#define LT_LOG_FD(log_fmt) \
168+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd);
169+#define LT_LOG_FD_ERROR(log_fmt) \
170+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \
171+ fd, errno, std::strerror(errno));
172+#define LT_LOG_FD_SIN(log_fmt) \
173+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \
174+ fd, sin_pretty_str(sa.get()).c_str());
175+#define LT_LOG_FD_SIN6(log_fmt) \
176+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \
177+ fd, sin6_pretty_str(sa.get()).c_str());
178+
179+namespace torrent {
180+
181+auto detect_local_sin_addr() -> sin_unique_ptr {
182+ int fd = fd_open(fd_flag_v4only | fd_flag_datagram);
183+ if (fd == -1) {
184+ LT_LOG_ERROR("detect_local_sin_addr: open failed");
185+ return sin_unique_ptr();
186+ }
187+
188+ // TODO: Check if unique_ptr works.
189+ std::shared_ptr<void> _fd(nullptr, [fd](...){ fd_close(fd); });
190+
191+ auto connectAddress = sin_make();
192+ connectAddress.get()->sin_addr.s_addr = htonl(0x04000001);
193+ connectAddress.get()->sin_port = 80;
194+
195+ if (!fd_connect(fd, reinterpret_cast<sockaddr*>(connectAddress.get())) && errno != EINPROGRESS) {
196+ LT_LOG_FD_ERROR("detect_local_sin_addr: connect failed");
197+ return sin_unique_ptr();
198+ }
199+
200+ // TODO: Make sa function.
201+ socklen_t socklen = sizeof(sockaddr_in);
202+
203+ auto sa = sin_make();
204+
205+ if (::getsockname(fd, reinterpret_cast<sockaddr*>(sa.get()), &socklen) != 0) {
206+ LT_LOG_FD_ERROR("detect_local_sin_addr: getsockname failed");
207+ return sin_unique_ptr();
208+ }
209+ if (socklen != sizeof(sockaddr_in)) {
210+ LT_LOG_FD("detect_local_sin_addr: getsockname failed, invalid socklen");
211+ return sin_unique_ptr();
212+ }
213+
214+ LT_LOG_FD_SIN("detect_local_sin_addr: success");
215+
216+ return sa;
217+}
218+
219+auto detect_local_sin6_addr() -> sin6_unique_ptr {
220+ int fd = fd_open(fd_flag_v6only | fd_flag_datagram);
221+ if (fd == -1) {
222+ LT_LOG_ERROR("detect_local_sin6_addr: open failed");
223+ return sin6_unique_ptr();
224+ }
225+
226+ // TODO: Check if unique_ptr works.
227+ std::shared_ptr<void> _fd(nullptr, [fd](...){ fd_close(fd); });
228+
229+ auto connectAddress = sin6_make();
230+ connectAddress.get()->sin6_addr.s6_addr[0] = 0x20;
231+ connectAddress.get()->sin6_addr.s6_addr[1] = 0x01;
232+ connectAddress.get()->sin6_addr.s6_addr[15] = 0x01;
233+ connectAddress.get()->sin6_port = 80;
234+
235+ if (!fd_connect(fd, reinterpret_cast<sockaddr*>(connectAddress.get())) && errno != EINPROGRESS) {
236+ LT_LOG_FD_ERROR("detect_local_sin6_addr: connect failed");
237+ return sin6_unique_ptr();
238+ }
239+
240+ // TODO: Make sa function.
241+ socklen_t socklen = sizeof(sockaddr_in6);
242+
243+ auto sa = sin6_make();
244+
245+ if (::getsockname(fd, reinterpret_cast<sockaddr*>(sa.get()), &socklen) != 0) {
246+ LT_LOG_FD_ERROR("detect_local_sin6_addr: getsockname failed");
247+ return sin6_unique_ptr();
248+ }
249+ if (socklen != sizeof(sockaddr_in6)) {
250+ LT_LOG_FD("detect_local_sin6_addr: getsockname failed, invalid socklen");
251+ return sin6_unique_ptr();
252+ }
253+
254+ LT_LOG_FD_SIN6("detect_local_sin6_addr: success");
255+
256+ return sa;
257+}
258+
259+}
260diff --git a/src/torrent/net/utils.h b/src/torrent/net/utils.h
261new file mode 100755
262index 00000000..1d550c51
263--- /dev/null
264+++ b/src/torrent/net/utils.h
265@@ -0,0 +1,9 @@
266+#import <torrent/common.h>
267+#import <torrent/net/socket_address.h>
268+
269+namespace torrent {
270+
271+auto detect_local_sin_addr() -> sin_unique_ptr;
272+auto detect_local_sin6_addr() -> sin6_unique_ptr;
273+
274+}
275diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
276index 1bf94107..de3a39ab 100644
277--- a/src/tracker/tracker_http.cc
278+++ b/src/tracker/tracker_http.cc
279@@ -1,63 +1,29 @@
280-// libTorrent - BitTorrent library
281-// Copyright (C) 2005-2011, Jari Sundell
282-//
283-// This program is free software; you can redistribute it and/or modify
284-// it under the terms of the GNU General Public License as published by
285-// the Free Software Foundation; either version 2 of the License, or
286-// (at your option) any later version.
287-//
288-// This program is distributed in the hope that it will be useful,
289-// but WITHOUT ANY WARRANTY; without even the implied warranty of
290-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
291-// GNU General Public License for more details.
292-//
293-// You should have received a copy of the GNU General Public License
294-// along with this program; if not, write to the Free Software
295-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
296-//
297-// In addition, as a special exception, the copyright holders give
298-// permission to link the code of portions of this program with the
299-// OpenSSL library under certain conditions as described in each
300-// individual source file, and distribute linked combinations
301-// including the two.
302-//
303-// You must obey the GNU General Public License in all respects for
304-// all of the code used other than OpenSSL. If you modify file(s)
305-// with this exception, you may extend this exception to your version
306-// of the file(s), but you are not obligated to do so. If you do not
307-// wish to do so, delete this exception statement from your version.
308-// If you delete this exception statement from all source files in the
309-// program, then also delete it here.
310-//
311-// Contact: Jari Sundell <jaris@ifi.uio.no>
312-//
313-// Skomakerveien 33
314-// 3185 Skoppum, NORWAY
315-
316-#include "config.h"
317+#import "config.h"
318
319 #define __STDC_FORMAT_MACROS
320
321-#include <iomanip>
322-#include <sstream>
323-#include <rak/functional.h>
324-#include <rak/string_manip.h>
325-
326-#include "net/address_list.h"
327-#include "net/local_addr.h"
328-#include "torrent/connection_manager.h"
329-#include "torrent/download_info.h"
330-#include "torrent/exceptions.h"
331-#include "torrent/http.h"
332-#include "torrent/object_stream.h"
333-#include "torrent/tracker_list.h"
334-#include "torrent/utils/log.h"
335-#include "torrent/utils/option_strings.h"
336-
337-#include "tracker_http.h"
338-
339-#include "globals.h"
340-#include "manager.h"
341+#import <iomanip>
342+#import <sstream>
343+#import <rak/functional.h>
344+#import <rak/string_manip.h>
345+
346+#import "net/address_list.h"
347+#import "net/local_addr.h"
348+#import "torrent/connection_manager.h"
349+#import "torrent/download_info.h"
350+#import "torrent/exceptions.h"
351+#import "torrent/http.h"
352+#import "torrent/net/utils.h"
353+#import "torrent/net/socket_address.h"
354+#import "torrent/object_stream.h"
355+#import "torrent/tracker_list.h"
356+#import "torrent/utils/log.h"
357+#import "torrent/utils/option_strings.h"
358+
359+#import "tracker_http.h"
360+
361+#import "globals.h"
362+#import "manager.h"
363
364 #define LT_LOG_TRACKER(log_level, log_fmt, ...) \
365 lt_log_print_info(LOG_TRACKER_##log_level, m_parent->info(), "tracker", "[%u] " log_fmt, group(), __VA_ARGS__);
366@@ -142,19 +108,19 @@ TrackerHttp::send_state(int state) {
367
368 const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address());
369
370- if (!localAddress->is_address_any())
371- s << "&ip=" << localAddress->address_str();
372-
373- if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) {
374- rak::socket_address local_v6;
375- if (get_local_address(rak::socket_address::af_inet6, &local_v6))
376- s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str());
377- }
378+ if (localAddress->is_address_any()) {
379+ auto ipv4_address = detect_local_sin_addr();
380+ auto ipv6_address = detect_local_sin6_addr();
381
382- if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) {
383- rak::socket_address local_v4;
384- if (get_local_address(rak::socket_address::af_inet, &local_v4))
385- s << "&ipv4=" << local_v4.address_str();
386+ if (ipv4_address != nullptr) {
387+ s << "&ipv4=" << sin_addr_str(ipv4_address.get());
388+ }
389+ if (ipv6_address != nullptr) {
390+ s << "&ipv6=" << sin6_addr_str(ipv6_address.get());
391+ }
392+
393+ } else {
394+ s << "&ip=" << localAddress->address_str();
395 }
396
397 if (info->is_compact())
398diff --git a/test/helpers/network.h b/test/helpers/network.h
399index 6cf2f870..eb188426 100644
400--- a/test/helpers/network.h
401+++ b/test/helpers/network.h
402@@ -112,6 +112,7 @@ wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const
403
404 CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
405 sa != nullptr);
406+
407 return sa;
408 }
409
410@@ -121,6 +122,7 @@ wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, con
411
412 CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
413 sa != nullptr);
414+
415 return torrent::c_sa_unique_ptr(sa.release());
416 }
417
418diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc
419index 5e56f0f3..0a00ccd4 100644
420--- a/test/torrent/net/test_fd.cc
421+++ b/test/torrent/net/test_fd.cc
422@@ -9,13 +9,22 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
423 void
424 test_fd::test_valid_flags() {
425 CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
426+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram));
427+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_datagram));
428+
429 CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
430 CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
431 CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
432 CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
433
434+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_nonblock));
435+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_reuse_address));
436+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only));
437+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v6only));
438+
439 CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
440 CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
441+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
442
443 CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
444 CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
445diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc
446index 8a1b0c8a..a27b38bc 100644
447--- a/test/torrent/net/test_socket_address.cc
448+++ b/test/torrent/net/test_socket_address.cc
449@@ -83,7 +83,7 @@ test_socket_address::test_make() {
450 CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6);
451 CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0);
452 CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0);
453- CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0}));
454+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, (in6_addr{0})));
455 CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0);
456
457 torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix("");
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch
new file mode 100644
index 0000000000..923f5c97cd
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch
@@ -0,0 +1,85 @@
1From e646ed5427b690b75208510d328457af66b208e8 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Mon, 21 Jun 2021 21:12:56 +0900
4Subject: [PATCH] Added ipv6 options.
5
6---
7 src/torrent/connection_manager.cc | 6 +++++-
8 src/torrent/connection_manager.h | 13 +++++++++++++
9 src/tracker/tracker_http.cc | 13 +++++--------
10 3 files changed, 23 insertions(+), 9 deletions(-)
11
12diff --git a/src/torrent/connection_manager.cc b/src/torrent/connection_manager.cc
13index 972dcbfc..ea5efc58 100644
14--- a/src/torrent/connection_manager.cc
15+++ b/src/torrent/connection_manager.cc
16@@ -89,7 +89,11 @@ ConnectionManager::ConnectionManager() :
17
18 m_listen(new Listen),
19 m_listen_port(0),
20- m_listen_backlog(SOMAXCONN) {
21+ m_listen_backlog(SOMAXCONN),
22+
23+ m_block_ipv4(false),
24+ m_block_ipv6(false),
25+ m_prefer_ipv6(false) {
26
27 m_bindAddress = (new rak::socket_address())->c_sockaddr();
28 m_localAddress = (new rak::socket_address())->c_sockaddr();
29diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h
30index cf43b0bf..09ccdd28 100644
31--- a/src/torrent/connection_manager.h
32+++ b/src/torrent/connection_manager.h
33@@ -167,6 +167,15 @@ public:
34 // For internal usage.
35 Listen* listen() { return m_listen; }
36
37+ bool is_block_ipv4() const { return m_block_ipv4; }
38+ void set_block_ipv4(bool v) { m_block_ipv4 = v; }
39+
40+ bool is_block_ipv6() const { return m_block_ipv6; }
41+ void set_block_ipv6(bool v) { m_block_ipv6 = v; }
42+
43+ bool is_prefer_ipv6() const { return m_prefer_ipv6; }
44+ void set_prefer_ipv6(bool v) { m_prefer_ipv6 = v; }
45+
46 private:
47 ConnectionManager(const ConnectionManager&);
48 void operator = (const ConnectionManager&);
49@@ -190,6 +199,10 @@ private:
50 slot_filter_type m_slot_filter;
51 slot_resolver_type m_slot_resolver;
52 slot_throttle_type m_slot_address_throttle;
53+
54+ bool m_block_ipv4;
55+ bool m_block_ipv6;
56+ bool m_prefer_ipv6;
57 };
58
59 }
60diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
61index de3a39ab..fdbbd58a 100644
62--- a/src/tracker/tracker_http.cc
63+++ b/src/tracker/tracker_http.cc
64@@ -109,16 +109,13 @@ TrackerHttp::send_state(int state) {
65 const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address());
66
67 if (localAddress->is_address_any()) {
68- auto ipv4_address = detect_local_sin_addr();
69- auto ipv6_address = detect_local_sin6_addr();
70+ if (manager->connection_manager()->is_prefer_ipv6()) {
71+ auto ipv6_address = detect_local_sin6_addr();
72
73- if (ipv4_address != nullptr) {
74- s << "&ipv4=" << sin_addr_str(ipv4_address.get());
75+ if (ipv6_address != nullptr) {
76+ s << "&ip=" << sin6_addr_str(ipv6_address.get());
77+ }
78 }
79- if (ipv6_address != nullptr) {
80- s << "&ipv6=" << sin6_addr_str(ipv6_address.get());
81- }
82-
83 } else {
84 s << "&ip=" << localAddress->address_str();
85 }
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch
new file mode 100644
index 0000000000..383984179d
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch
@@ -0,0 +1,444 @@
1From 54caef85baca975e0be30b4f3f6de01db19c8e19 Mon Sep 17 00:00:00 2001
2From: rakshasa <sundell.software@gmail.com>
3Date: Mon, 21 Jun 2021 21:28:02 +0900
4Subject: [PATCH] Removed obsolete files.
5
6---
7 src/Makefile.am | 2 -
8 src/net/local_addr.cc | 329 ------------------------------------
9 src/net/local_addr.h | 64 -------
10 src/tracker/tracker_http.cc | 1 -
11 4 files changed, 396 deletions(-)
12 delete mode 100644 src/net/local_addr.cc
13 delete mode 100644 src/net/local_addr.h
14
15diff --git a/src/Makefile.am b/src/Makefile.am
16index 95e6a7ae..925e7e15 100644
17--- a/src/Makefile.am
18+++ b/src/Makefile.am
19@@ -76,8 +76,6 @@ libtorrent_other_la_SOURCES = \
20 net/address_list.cc \
21 net/address_list.h \
22 net/data_buffer.h \
23- net/local_addr.cc \
24- net/local_addr.h \
25 net/listen.cc \
26 net/listen.h \
27 net/protocol_buffer.h \
28diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc
29deleted file mode 100644
30index 0c7116cb..00000000
31--- a/src/net/local_addr.cc
32+++ /dev/null
33@@ -1,329 +0,0 @@
34-// libTorrent - BitTorrent library
35-// Copyright (C) 2005-2007, Jari Sundell
36-//
37-// This program is free software; you can redistribute it and/or modify
38-// it under the terms of the GNU General Public License as published by
39-// the Free Software Foundation; either version 2 of the License, or
40-// (at your option) any later version.
41-//
42-// This program is distributed in the hope that it will be useful,
43-// but WITHOUT ANY WARRANTY; without even the implied warranty of
44-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45-// GNU General Public License for more details.
46-//
47-// You should have received a copy of the GNU General Public License
48-// along with this program; if not, write to the Free Software
49-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
50-//
51-// In addition, as a special exception, the copyright holders give
52-// permission to link the code of portions of this program with the
53-// OpenSSL library under certain conditions as described in each
54-// individual source file, and distribute linked combinations
55-// including the two.
56-//
57-// You must obey the GNU General Public License in all respects for
58-// all of the code used other than OpenSSL. If you modify file(s)
59-// with this exception, you may extend this exception to your version
60-// of the file(s), but you are not obligated to do so. If you do not
61-// wish to do so, delete this exception statement from your version.
62-// If you delete this exception statement from all source files in the
63-// program, then also delete it here.
64-//
65-// Contact: Jari Sundell <jaris@ifi.uio.no>
66-//
67-// Skomakerveien 33
68-// 3185 Skoppum, NORWAY
69-
70-// TODO: Remove.
71-
72-#include "config.h"
73-
74-#include <stdio.h>
75-#include <rak/socket_address.h>
76-#include <sys/types.h>
77-#include <errno.h>
78-
79-#ifdef __linux__
80-#include <linux/netlink.h>
81-#include <linux/rtnetlink.h>
82-#endif
83-
84-#include "torrent/exceptions.h"
85-#include "socket_fd.h"
86-#include "local_addr.h"
87-
88-namespace torrent {
89-
90-#ifdef __linux__
91-
92-namespace {
93-
94-// IPv4 priority, from highest to lowest:
95-//
96-// 1. Everything else (global address)
97-// 2. Private address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
98-// 3. Empty/INADDR_ANY (0.0.0.0)
99-// 4. Link-local address (169.254.0.0/16)
100-// 5. Localhost (127.0.0.0/8)
101-int
102-get_priority_ipv4(const in_addr& addr) {
103- if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x7f000000U)) {
104- return 5;
105- }
106- if ((addr.s_addr & htonl(0xffff0000U)) == htonl(0xa9fe0000U)) {
107- return 4;
108- }
109- if (addr.s_addr == htonl(0)) {
110- return 3;
111- }
112- if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x0a000000U) ||
113- (addr.s_addr & htonl(0xfff00000U)) == htonl(0xac100000U) ||
114- (addr.s_addr & htonl(0xffff0000U)) == htonl(0xc0a80000U)) {
115- return 2;
116- }
117- return 1;
118-}
119-
120-// IPv6 priority, from highest to lowest:
121-//
122-// 1. Global address (2000::/16 not in 6to4 or Teredo)
123-// 2. 6to4 (2002::/16)
124-// 3. Teredo (2001::/32)
125-// 4. Empty/INADDR_ANY (::)
126-// 5. Everything else (link-local, ULA, etc.)
127-int
128-get_priority_ipv6(const in6_addr& addr) {
129- const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(addr.s6_addr);
130- if (addr32[0] == htonl(0) &&
131- addr32[1] == htonl(0) &&
132- addr32[2] == htonl(0) &&
133- addr32[3] == htonl(0)) {
134- return 4;
135- }
136- if (addr32[0] == htonl(0x20010000)) {
137- return 3;
138- }
139- if ((addr32[0] & htonl(0xffff0000)) == htonl(0x20020000)) {
140- return 2;
141- }
142- if ((addr32[0] & htonl(0xe0000000)) == htonl(0x20000000)) {
143- return 1;
144- }
145- return 5;
146-}
147-
148-int
149-get_priority(const rak::socket_address& addr) {
150- switch (addr.family()) {
151- case AF_INET:
152- return get_priority_ipv4(addr.c_sockaddr_inet()->sin_addr);
153- case AF_INET6:
154- return get_priority_ipv6(addr.c_sockaddr_inet6()->sin6_addr);
155- default:
156- throw torrent::internal_error("Unknown address family given to compare");
157- }
158-}
159-
160-}
161-
162-// Linux-specific implementation that understands how to filter away
163-// understands how to filter away secondary addresses.
164-bool get_local_address(sa_family_t family, rak::socket_address *address) {
165- rak::socket_address best_addr;
166- switch (family) {
167- case AF_INET:
168- best_addr.sa_inet()->clear();
169- break;
170- case AF_INET6:
171- best_addr.sa_inet6()->clear();
172- break;
173- default:
174- throw torrent::internal_error("Unknown address family given to get_local_address");
175- }
176-
177- // The bottom bit of the priority is used to hold if the address is
178- // a secondary address (e.g. with IPv6 privacy extensions) or not;
179- // secondary addresses have lower priority (higher number).
180- int best_addr_pri = get_priority(best_addr) * 2;
181-
182- // Get all the addresses via Linux' netlink interface.
183- int fd = ::socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
184- if (fd == -1) {
185- return false;
186- }
187-
188- struct sockaddr_nl nladdr;
189- memset(&nladdr, 0, sizeof(nladdr));
190- nladdr.nl_family = AF_NETLINK;
191- if (::bind(fd, (sockaddr *)&nladdr, sizeof(nladdr))) {
192- ::close(fd);
193- return false;
194- }
195-
196- const int seq_no = 1;
197- struct {
198- nlmsghdr nh;
199- rtgenmsg g;
200- } req;
201- memset(&req, 0, sizeof(req));
202-
203- req.nh.nlmsg_len = sizeof(req);
204- req.nh.nlmsg_type = RTM_GETADDR;
205- req.nh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
206- req.nh.nlmsg_pid = getpid();
207- req.nh.nlmsg_seq = seq_no;
208- req.g.rtgen_family = AF_UNSPEC;
209-
210- int ret;
211- do {
212- ret = ::sendto(fd, &req, sizeof(req), 0, (sockaddr *)&nladdr, sizeof(nladdr));
213- } while (ret == -1 && errno == EINTR);
214-
215- if (ret == -1) {
216- ::close(fd);
217- return false;
218- }
219-
220- bool done = false;
221- do {
222- char buf[4096];
223- socklen_t len = sizeof(nladdr);
224- do {
225- ret = ::recvfrom(fd, buf, sizeof(buf), 0, (sockaddr *)&nladdr, &len);
226- } while (ret == -1 && errno == EINTR);
227-
228- if (ret < 0) {
229- ::close(fd);
230- return false;
231- }
232-
233- for (const nlmsghdr *nlmsg = (const nlmsghdr *)buf;
234- NLMSG_OK(nlmsg, ret);
235- nlmsg = NLMSG_NEXT(nlmsg, ret)) {
236- if (nlmsg->nlmsg_seq != seq_no)
237- continue;
238- if (nlmsg->nlmsg_type == NLMSG_DONE) {
239- done = true;
240- break;
241- }
242- if (nlmsg->nlmsg_type == NLMSG_ERROR) {
243- ::close(fd);
244- return false;
245- }
246- if (nlmsg->nlmsg_type != RTM_NEWADDR)
247- continue;
248-
249- const ifaddrmsg *ifa = (const ifaddrmsg *)NLMSG_DATA(nlmsg);
250-
251- if (ifa->ifa_family != family)
252- continue;
253-
254-#ifdef IFA_F_OPTIMISTIC
255- if ((ifa->ifa_flags & IFA_F_OPTIMISTIC) != 0)
256- continue;
257-#endif
258-#ifdef IFA_F_DADFAILED
259- if ((ifa->ifa_flags & IFA_F_DADFAILED) != 0)
260- continue;
261-#endif
262-#ifdef IFA_F_DEPRECATED
263- if ((ifa->ifa_flags & IFA_F_DEPRECATED) != 0)
264- continue;
265-#endif
266-#ifdef IFA_F_TENTATIVE
267- if ((ifa->ifa_flags & IFA_F_TENTATIVE) != 0)
268- continue;
269-#endif
270-
271- // Since there can be point-to-point links on the machine, we need to keep
272- // track of the addresses we've seen for this interface; if we see both
273- // IFA_LOCAL and IFA_ADDRESS for an interface, keep only the IFA_LOCAL.
274- rak::socket_address this_addr;
275- bool seen_addr = false;
276- int plen = IFA_PAYLOAD(nlmsg);
277- for (const rtattr *rta = IFA_RTA(ifa);
278- RTA_OK(rta, plen);
279- rta = RTA_NEXT(rta, plen)) {
280- if (rta->rta_type != IFA_LOCAL &&
281- rta->rta_type != IFA_ADDRESS) {
282- continue;
283- }
284- if (rta->rta_type == IFA_ADDRESS && seen_addr) {
285- continue;
286- }
287- seen_addr = true;
288- switch (ifa->ifa_family) {
289- case AF_INET:
290- this_addr.sa_inet()->clear();
291- this_addr.sa_inet()->set_address(*(const in_addr *)RTA_DATA(rta));
292- break;
293- case AF_INET6:
294- this_addr.sa_inet6()->clear();
295- this_addr.sa_inet6()->set_address(*(const in6_addr *)RTA_DATA(rta));
296- break;
297- }
298- }
299- if (!seen_addr)
300- continue;
301-
302- int this_addr_pri = get_priority(this_addr) * 2;
303- if ((ifa->ifa_flags & IFA_F_SECONDARY) == IFA_F_SECONDARY) {
304- ++this_addr_pri;
305- }
306-
307- if (this_addr_pri < best_addr_pri) {
308- best_addr = this_addr;
309- best_addr_pri = this_addr_pri;
310- }
311- }
312- } while (!done);
313-
314- ::close(fd);
315- if (!best_addr.is_address_any()) {
316- *address = best_addr;
317- return true;
318- } else {
319- return false;
320- }
321-}
322-
323-#else
324-
325-// Generic POSIX variant.
326-bool
327-get_local_address(sa_family_t family, rak::socket_address *address) {
328- SocketFd sock;
329- if (!sock.open_datagram()) {
330- return false;
331- }
332-
333- rak::socket_address dummy_dest;
334- dummy_dest.clear();
335-
336- switch (family) {
337- case rak::socket_address::af_inet:
338- dummy_dest.set_address_c_str("4.0.0.0");
339- break;
340- case rak::socket_address::af_inet6:
341- dummy_dest.set_address_c_str("2001:1::");
342- break;
343- default:
344- throw internal_error("Unknown address family");
345- }
346-
347- dummy_dest.set_port(80);
348-
349- if (!sock.connect(dummy_dest)) {
350- sock.close();
351- return false;
352- }
353-
354- bool ret = sock.getsockname(address);
355- sock.close();
356-
357- return ret;
358-}
359-
360-#endif
361-
362-}
363diff --git a/src/net/local_addr.h b/src/net/local_addr.h
364deleted file mode 100644
365index 43bc8206..00000000
366--- a/src/net/local_addr.h
367+++ /dev/null
368@@ -1,64 +0,0 @@
369-// libTorrent - BitTorrent library
370-// Copyright (C) 2005-2007, Jari Sundell
371-//
372-// This program is free software; you can redistribute it and/or modify
373-// it under the terms of the GNU General Public License as published by
374-// the Free Software Foundation; either version 2 of the License, or
375-// (at your option) any later version.
376-//
377-// This program is distributed in the hope that it will be useful,
378-// but WITHOUT ANY WARRANTY; without even the implied warranty of
379-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
380-// GNU General Public License for more details.
381-//
382-// You should have received a copy of the GNU General Public License
383-// along with this program; if not, write to the Free Software
384-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
385-//
386-// In addition, as a special exception, the copyright holders give
387-// permission to link the code of portions of this program with the
388-// OpenSSL library under certain conditions as described in each
389-// individual source file, and distribute linked combinations
390-// including the two.
391-//
392-// You must obey the GNU General Public License in all respects for
393-// all of the code used other than OpenSSL. If you modify file(s)
394-// with this exception, you may extend this exception to your version
395-// of the file(s), but you are not obligated to do so. If you do not
396-// wish to do so, delete this exception statement from your version.
397-// If you delete this exception statement from all source files in the
398-// program, then also delete it here.
399-//
400-// Contact: Jari Sundell <jaris@ifi.uio.no>
401-//
402-// Skomakerveien 33
403-// 3185 Skoppum, NORWAY
404-
405-// A routine to get a local IP address that can be presented to a tracker.
406-// (Does not use UPnP etc., so will not understand NAT.)
407-// On a machine with multiple network cards, address selection can be a
408-// complex process, and in general what's selected is a source/destination
409-// address pair. However, this routine will give an approximation that will
410-// be good enough for most purposes and users.
411-
412-#ifndef LIBTORRENT_NET_LOCAL_ADDR_H
413-#define LIBTORRENT_NET_LOCAL_ADDR_H
414-
415-#include <unistd.h>
416-
417-namespace rak {
418- class socket_address;
419-}
420-
421-namespace torrent {
422-
423-// Note: family must currently be rak::af_inet or rak::af_inet6
424-// (rak::af_unspec won't do); anything else will throw an exception.
425-// Returns false if no address of the given family could be found,
426-// either because there are none, or because something went wrong in
427-// the process (e.g., no free file descriptors).
428-bool get_local_address(sa_family_t family, rak::socket_address *address);
429-
430-}
431-
432-#endif /* LIBTORRENT_NET_LOCAL_ADDR_H */
433diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
434index fdbbd58a..22c409a1 100644
435--- a/src/tracker/tracker_http.cc
436+++ b/src/tracker/tracker_http.cc
437@@ -8,7 +8,6 @@
438 #import <rak/string_manip.h>
439
440 #import "net/address_list.h"
441-#import "net/local_addr.h"
442 #import "torrent/connection_manager.h"
443 #import "torrent/download_info.h"
444 #import "torrent/exceptions.h"
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch
new file mode 100644
index 0000000000..965f61a4e6
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch
@@ -0,0 +1,2979 @@
1From 4cfe9b1dc1349ad167969d6cf87f557600f34a2e Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Sat, 7 Aug 2021 17:49:35 +0900
4Subject: [PATCH] Updated and cleaned up automake. (#224)
5
6---
7 INSTALL | 371 +++++++----
8 autogen.sh | 51 --
9 configure.ac | 32 +-
10 scripts/ax_check_zlib.m4 | 11 +-
11 scripts/ax_cxx_compile_stdcxx.m4 | 962 ++++++++++++++++++++++++++++
12 scripts/ax_cxx_compile_stdcxx_0x.m4 | 106 ---
13 scripts/ax_cxx_compile_stdcxx_11.m4 | 147 -----
14 scripts/ax_pthread.m4 | 453 +++++++++----
15 scripts/checks.m4 | 104 ++-
16 scripts/common.m4 | 29 +-
17 scripts/rak_compiler.m4 | 6 +-
18 scripts/rak_cxx.m4 | 14 -
19 12 files changed, 1642 insertions(+), 644 deletions(-)
20 delete mode 100755 autogen.sh
21 mode change 100644 => 100755 scripts/ax_check_zlib.m4
22 create mode 100755 scripts/ax_cxx_compile_stdcxx.m4
23 delete mode 100644 scripts/ax_cxx_compile_stdcxx_0x.m4
24 delete mode 100644 scripts/ax_cxx_compile_stdcxx_11.m4
25 mode change 100644 => 100755 scripts/ax_pthread.m4
26 delete mode 100644 scripts/rak_cxx.m4
27
28diff --git a/INSTALL b/INSTALL
29index 54caf7c1..8865734f 100644
30--- a/INSTALL
31+++ b/INSTALL
32@@ -1,81 +1,109 @@
33-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
34+Installation Instructions
35+*************************
36+
37+ Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
38 Foundation, Inc.
39
40- This file is free documentation; the Free Software Foundation gives
41-unlimited permission to copy, distribute and modify it.
42+ Copying and distribution of this file, with or without modification,
43+are permitted in any medium without royalty provided the copyright
44+notice and this notice are preserved. This file is offered as-is,
45+without warranty of any kind.
46
47 Basic Installation
48 ==================
49
50- These are generic installation instructions.
51+ Briefly, the shell command './configure && make && make install'
52+should configure, build, and install this package. The following
53+more-detailed instructions are generic; see the 'README' file for
54+instructions specific to this package. Some packages provide this
55+'INSTALL' file but do not implement all of the features documented
56+below. The lack of an optional feature in a given package is not
57+necessarily a bug. More recommendations for GNU packages can be found
58+in *note Makefile Conventions: (standards)Makefile Conventions.
59
60- The `configure' shell script attempts to guess correct values for
61+ The 'configure' shell script attempts to guess correct values for
62 various system-dependent variables used during compilation. It uses
63-those values to create a `Makefile' in each directory of the package.
64-It may also create one or more `.h' files containing system-dependent
65-definitions. Finally, it creates a shell script `config.status' that
66+those values to create a 'Makefile' in each directory of the package.
67+It may also create one or more '.h' files containing system-dependent
68+definitions. Finally, it creates a shell script 'config.status' that
69 you can run in the future to recreate the current configuration, and a
70-file `config.log' containing compiler output (useful mainly for
71-debugging `configure').
72+file 'config.log' containing compiler output (useful mainly for
73+debugging 'configure').
74
75- It can also use an optional file (typically called `config.cache'
76-and enabled with `--cache-file=config.cache' or simply `-C') that saves
77-the results of its tests to speed up reconfiguring. (Caching is
78-disabled by default to prevent problems with accidental use of stale
79-cache files.)
80+ It can also use an optional file (typically called 'config.cache' and
81+enabled with '--cache-file=config.cache' or simply '-C') that saves the
82+results of its tests to speed up reconfiguring. Caching is disabled by
83+default to prevent problems with accidental use of stale cache files.
84
85 If you need to do unusual things to compile the package, please try
86-to figure out how `configure' could check whether to do them, and mail
87-diffs or instructions to the address given in the `README' so they can
88+to figure out how 'configure' could check whether to do them, and mail
89+diffs or instructions to the address given in the 'README' so they can
90 be considered for the next release. If you are using the cache, and at
91-some point `config.cache' contains results you don't want to keep, you
92+some point 'config.cache' contains results you don't want to keep, you
93 may remove or edit it.
94
95- The file `configure.ac' (or `configure.in') is used to create
96-`configure' by a program called `autoconf'. You only need
97-`configure.ac' if you want to change it or regenerate `configure' using
98-a newer version of `autoconf'.
99+ The file 'configure.ac' (or 'configure.in') is used to create
100+'configure' by a program called 'autoconf'. You need 'configure.ac' if
101+you want to change it or regenerate 'configure' using a newer version of
102+'autoconf'.
103+
104+ The simplest way to compile this package is:
105
106-The simplest way to compile this package is:
107+ 1. 'cd' to the directory containing the package's source code and type
108+ './configure' to configure the package for your system.
109
110- 1. `cd' to the directory containing the package's source code and type
111- `./configure' to configure the package for your system. If you're
112- using `csh' on an old version of System V, you might need to type
113- `sh ./configure' instead to prevent `csh' from trying to execute
114- `configure' itself.
115+ Running 'configure' might take a while. While running, it prints
116+ some messages telling which features it is checking for.
117
118- Running `configure' takes awhile. While running, it prints some
119- messages telling which features it is checking for.
120+ 2. Type 'make' to compile the package.
121
122- 2. Type `make' to compile the package.
123+ 3. Optionally, type 'make check' to run any self-tests that come with
124+ the package, generally using the just-built uninstalled binaries.
125
126- 3. Optionally, type `make check' to run any self-tests that come with
127- the package.
128+ 4. Type 'make install' to install the programs and any data files and
129+ documentation. When installing into a prefix owned by root, it is
130+ recommended that the package be configured and built as a regular
131+ user, and only the 'make install' phase executed with root
132+ privileges.
133
134- 4. Type `make install' to install the programs and any data files and
135- documentation.
136+ 5. Optionally, type 'make installcheck' to repeat any self-tests, but
137+ this time using the binaries in their final installed location.
138+ This target does not install anything. Running this target as a
139+ regular user, particularly if the prior 'make install' required
140+ root privileges, verifies that the installation completed
141+ correctly.
142
143- 5. You can remove the program binaries and object files from the
144- source code directory by typing `make clean'. To also remove the
145- files that `configure' created (so you can compile the package for
146- a different kind of computer), type `make distclean'. There is
147- also a `make maintainer-clean' target, but that is intended mainly
148+ 6. You can remove the program binaries and object files from the
149+ source code directory by typing 'make clean'. To also remove the
150+ files that 'configure' created (so you can compile the package for
151+ a different kind of computer), type 'make distclean'. There is
152+ also a 'make maintainer-clean' target, but that is intended mainly
153 for the package's developers. If you use it, you may have to get
154 all sorts of other programs in order to regenerate files that came
155 with the distribution.
156
157+ 7. Often, you can also type 'make uninstall' to remove the installed
158+ files again. In practice, not all packages have tested that
159+ uninstallation works correctly, even though it is required by the
160+ GNU Coding Standards.
161+
162+ 8. Some packages, particularly those that use Automake, provide 'make
163+ distcheck', which can by used by developers to test that all other
164+ targets like 'make install' and 'make uninstall' work correctly.
165+ This target is generally not run by end users.
166+
167 Compilers and Options
168 =====================
169
170 Some systems require unusual options for compilation or linking that
171-the `configure' script does not know about. Run `./configure --help'
172+the 'configure' script does not know about. Run './configure --help'
173 for details on some of the pertinent environment variables.
174
175- You can give `configure' initial values for configuration parameters
176-by setting variables in the command line or in the environment. Here
177-is an example:
178+ You can give 'configure' initial values for configuration parameters
179+by setting variables in the command line or in the environment. Here is
180+an example:
181
182- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
183+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
184
185 *Note Defining Variables::, for more details.
186
187@@ -84,146 +112,257 @@ Compiling For Multiple Architectures
188
189 You can compile the package for more than one kind of computer at the
190 same time, by placing the object files for each architecture in their
191-own directory. To do this, you must use a version of `make' that
192-supports the `VPATH' variable, such as GNU `make'. `cd' to the
193+own directory. To do this, you can use GNU 'make'. 'cd' to the
194 directory where you want the object files and executables to go and run
195-the `configure' script. `configure' automatically checks for the
196-source code in the directory that `configure' is in and in `..'.
197+the 'configure' script. 'configure' automatically checks for the source
198+code in the directory that 'configure' is in and in '..'. This is known
199+as a "VPATH" build.
200+
201+ With a non-GNU 'make', it is safer to compile the package for one
202+architecture at a time in the source code directory. After you have
203+installed the package for one architecture, use 'make distclean' before
204+reconfiguring for another architecture.
205+
206+ On MacOS X 10.5 and later systems, you can create libraries and
207+executables that work on multiple system types--known as "fat" or
208+"universal" binaries--by specifying multiple '-arch' options to the
209+compiler but only a single '-arch' option to the preprocessor. Like
210+this:
211+
212+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
213+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
214+ CPP="gcc -E" CXXCPP="g++ -E"
215
216- If you have to use a `make' that does not support the `VPATH'
217-variable, you have to compile the package for one architecture at a
218-time in the source code directory. After you have installed the
219-package for one architecture, use `make distclean' before reconfiguring
220-for another architecture.
221+ This is not guaranteed to produce working output in all cases, you
222+may have to build one architecture at a time and combine the results
223+using the 'lipo' tool if you have problems.
224
225 Installation Names
226 ==================
227
228- By default, `make install' will install the package's files in
229-`/usr/local/bin', `/usr/local/man', etc. You can specify an
230-installation prefix other than `/usr/local' by giving `configure' the
231-option `--prefix=PATH'.
232+ By default, 'make install' installs the package's commands under
233+'/usr/local/bin', include files under '/usr/local/include', etc. You
234+can specify an installation prefix other than '/usr/local' by giving
235+'configure' the option '--prefix=PREFIX', where PREFIX must be an
236+absolute file name.
237
238 You can specify separate installation prefixes for
239 architecture-specific files and architecture-independent files. If you
240-give `configure' the option `--exec-prefix=PATH', the package will use
241-PATH as the prefix for installing programs and libraries.
242-Documentation and other data files will still use the regular prefix.
243+pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
244+PREFIX as the prefix for installing programs and libraries.
245+Documentation and other data files still use the regular prefix.
246
247 In addition, if you use an unusual directory layout you can give
248-options like `--bindir=PATH' to specify different values for particular
249-kinds of files. Run `configure --help' for a list of the directories
250-you can set and what kinds of files go in them.
251-
252- If the package supports it, you can cause programs to be installed
253-with an extra prefix or suffix on their names by giving `configure' the
254-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
255+options like '--bindir=DIR' to specify different values for particular
256+kinds of files. Run 'configure --help' for a list of the directories
257+you can set and what kinds of files go in them. In general, the default
258+for these options is expressed in terms of '${prefix}', so that
259+specifying just '--prefix' will affect all of the other directory
260+specifications that were not explicitly provided.
261+
262+ The most portable way to affect installation locations is to pass the
263+correct locations to 'configure'; however, many packages provide one or
264+both of the following shortcuts of passing variable assignments to the
265+'make install' command line to change installation locations without
266+having to reconfigure or recompile.
267+
268+ The first method involves providing an override variable for each
269+affected directory. For example, 'make install
270+prefix=/alternate/directory' will choose an alternate location for all
271+directory configuration variables that were expressed in terms of
272+'${prefix}'. Any directories that were specified during 'configure',
273+but not in terms of '${prefix}', must each be overridden at install time
274+for the entire installation to be relocated. The approach of makefile
275+variable overrides for each directory variable is required by the GNU
276+Coding Standards, and ideally causes no recompilation. However, some
277+platforms have known limitations with the semantics of shared libraries
278+that end up requiring recompilation when using this method, particularly
279+noticeable in packages that use GNU Libtool.
280+
281+ The second method involves providing the 'DESTDIR' variable. For
282+example, 'make install DESTDIR=/alternate/directory' will prepend
283+'/alternate/directory' before all installation names. The approach of
284+'DESTDIR' overrides is not required by the GNU Coding Standards, and
285+does not work on platforms that have drive letters. On the other hand,
286+it does better at avoiding recompilation issues, and works well even
287+when some directory options were not specified in terms of '${prefix}'
288+at 'configure' time.
289
290 Optional Features
291 =================
292
293- Some packages pay attention to `--enable-FEATURE' options to
294-`configure', where FEATURE indicates an optional part of the package.
295-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
296-is something like `gnu-as' or `x' (for the X Window System). The
297-`README' should mention any `--enable-' and `--with-' options that the
298+ If the package supports it, you can cause programs to be installed
299+with an extra prefix or suffix on their names by giving 'configure' the
300+option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
301+
302+ Some packages pay attention to '--enable-FEATURE' options to
303+'configure', where FEATURE indicates an optional part of the package.
304+They may also pay attention to '--with-PACKAGE' options, where PACKAGE
305+is something like 'gnu-as' or 'x' (for the X Window System). The
306+'README' should mention any '--enable-' and '--with-' options that the
307 package recognizes.
308
309- For packages that use the X Window System, `configure' can usually
310+ For packages that use the X Window System, 'configure' can usually
311 find the X include and library files automatically, but if it doesn't,
312-you can use the `configure' options `--x-includes=DIR' and
313-`--x-libraries=DIR' to specify their locations.
314+you can use the 'configure' options '--x-includes=DIR' and
315+'--x-libraries=DIR' to specify their locations.
316+
317+ Some packages offer the ability to configure how verbose the
318+execution of 'make' will be. For these packages, running './configure
319+--enable-silent-rules' sets the default to minimal output, which can be
320+overridden with 'make V=1'; while running './configure
321+--disable-silent-rules' sets the default to verbose, which can be
322+overridden with 'make V=0'.
323+
324+Particular systems
325+==================
326+
327+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
328+is not installed, it is recommended to use the following options in
329+order to use an ANSI C compiler:
330+
331+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
332+
333+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
334+
335+ HP-UX 'make' updates targets which have the same time stamps as their
336+prerequisites, which makes it generally unusable when shipped generated
337+files such as 'configure' are involved. Use GNU 'make' instead.
338+
339+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
340+parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
341+workaround. If GNU CC is not installed, it is therefore recommended to
342+try
343+
344+ ./configure CC="cc"
345+
346+and if that doesn't work, try
347+
348+ ./configure CC="cc -nodtk"
349+
350+ On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
351+directory contains several dysfunctional programs; working variants of
352+these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
353+in your 'PATH', put it _after_ '/usr/bin'.
354+
355+ On Haiku, software installed for all users goes in '/boot/common',
356+not '/usr/local'. It is recommended to use the following options:
357+
358+ ./configure --prefix=/boot/common
359
360 Specifying the System Type
361 ==========================
362
363- There may be some features `configure' cannot figure out
364+ There may be some features 'configure' cannot figure out
365 automatically, but needs to determine by the type of machine the package
366 will run on. Usually, assuming the package is built to be run on the
367-_same_ architectures, `configure' can figure that out, but if it prints
368+_same_ architectures, 'configure' can figure that out, but if it prints
369 a message saying it cannot guess the machine type, give it the
370-`--build=TYPE' option. TYPE can either be a short name for the system
371-type, such as `sun4', or a canonical name which has the form:
372+'--build=TYPE' option. TYPE can either be a short name for the system
373+type, such as 'sun4', or a canonical name which has the form:
374
375 CPU-COMPANY-SYSTEM
376
377 where SYSTEM can have one of these forms:
378
379- OS KERNEL-OS
380+ OS
381+ KERNEL-OS
382
383- See the file `config.sub' for the possible values of each field. If
384-`config.sub' isn't included in this package, then this package doesn't
385+ See the file 'config.sub' for the possible values of each field. If
386+'config.sub' isn't included in this package, then this package doesn't
387 need to know the machine type.
388
389 If you are _building_ compiler tools for cross-compiling, you should
390-use the `--target=TYPE' option to select the type of system they will
391+use the option '--target=TYPE' to select the type of system they will
392 produce code for.
393
394 If you want to _use_ a cross compiler, that generates code for a
395 platform different from the build platform, you should specify the
396 "host" platform (i.e., that on which the generated programs will
397-eventually be run) with `--host=TYPE'.
398+eventually be run) with '--host=TYPE'.
399
400 Sharing Defaults
401 ================
402
403- If you want to set default values for `configure' scripts to share,
404-you can create a site shell script called `config.site' that gives
405-default values for variables like `CC', `cache_file', and `prefix'.
406-`configure' looks for `PREFIX/share/config.site' if it exists, then
407-`PREFIX/etc/config.site' if it exists. Or, you can set the
408-`CONFIG_SITE' environment variable to the location of the site script.
409-A warning: not all `configure' scripts look for a site script.
410+ If you want to set default values for 'configure' scripts to share,
411+you can create a site shell script called 'config.site' that gives
412+default values for variables like 'CC', 'cache_file', and 'prefix'.
413+'configure' looks for 'PREFIX/share/config.site' if it exists, then
414+'PREFIX/etc/config.site' if it exists. Or, you can set the
415+'CONFIG_SITE' environment variable to the location of the site script.
416+A warning: not all 'configure' scripts look for a site script.
417
418 Defining Variables
419 ==================
420
421 Variables not defined in a site shell script can be set in the
422-environment passed to `configure'. However, some packages may run
423+environment passed to 'configure'. However, some packages may run
424 configure again during the build, and the customized values of these
425 variables may be lost. In order to avoid this problem, you should set
426-them in the `configure' command line, using `VAR=value'. For example:
427+them in the 'configure' command line, using 'VAR=value'. For example:
428
429 ./configure CC=/usr/local2/bin/gcc
430
431-will cause the specified gcc to be used as the C compiler (unless it is
432+causes the specified 'gcc' to be used as the C compiler (unless it is
433 overridden in the site shell script).
434
435-`configure' Invocation
436+Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
437+Autoconf limitation. Until the limitation is lifted, you can use this
438+workaround:
439+
440+ CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
441+
442+'configure' Invocation
443 ======================
444
445- `configure' recognizes the following options to control how it
446+ 'configure' recognizes the following options to control how it
447 operates.
448
449-`--help'
450-`-h'
451- Print a summary of the options to `configure', and exit.
452+'--help'
453+'-h'
454+ Print a summary of all of the options to 'configure', and exit.
455+
456+'--help=short'
457+'--help=recursive'
458+ Print a summary of the options unique to this package's
459+ 'configure', and exit. The 'short' variant lists options used only
460+ in the top level, while the 'recursive' variant lists options also
461+ present in any nested packages.
462
463-`--version'
464-`-V'
465- Print the version of Autoconf used to generate the `configure'
466+'--version'
467+'-V'
468+ Print the version of Autoconf used to generate the 'configure'
469 script, and exit.
470
471-`--cache-file=FILE'
472+'--cache-file=FILE'
473 Enable the cache: use and save the results of the tests in FILE,
474- traditionally `config.cache'. FILE defaults to `/dev/null' to
475+ traditionally 'config.cache'. FILE defaults to '/dev/null' to
476 disable caching.
477
478-`--config-cache'
479-`-C'
480- Alias for `--cache-file=config.cache'.
481+'--config-cache'
482+'-C'
483+ Alias for '--cache-file=config.cache'.
484
485-`--quiet'
486-`--silent'
487-`-q'
488+'--quiet'
489+'--silent'
490+'-q'
491 Do not print messages saying which checks are being made. To
492- suppress all normal output, redirect it to `/dev/null' (any error
493+ suppress all normal output, redirect it to '/dev/null' (any error
494 messages will still be shown).
495
496-`--srcdir=DIR'
497+'--srcdir=DIR'
498 Look for the package's source code in directory DIR. Usually
499- `configure' can determine that directory automatically.
500+ 'configure' can determine that directory automatically.
501+
502+'--prefix=DIR'
503+ Use DIR as the installation prefix. *note Installation Names:: for
504+ more details, including other options available for fine-tuning the
505+ installation locations.
506
507-`configure' also accepts some other, not widely useful, options. Run
508-`configure --help' for more details.
509+'--no-create'
510+'-n'
511+ Run the configure checks, but stop before creating any output
512+ files.
513
514+'configure' also accepts some other, not widely useful, options. Run
515+'configure --help' for more details.
516diff --git a/autogen.sh b/autogen.sh
517deleted file mode 100755
518index 6def96dd..00000000
519--- a/autogen.sh
520+++ /dev/null
521@@ -1,51 +0,0 @@
522-#! /bin/sh
523-
524-echo aclocal...
525-(aclocal --version) < /dev/null > /dev/null 2>&1 || {
526- echo aclocal not found
527- exit 1
528-}
529-
530-aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1
531-
532-echo autoheader...
533-(autoheader --version) < /dev/null > /dev/null 2>&1 || {
534- echo autoheader not found
535- exit 1
536-}
537-
538-autoheader || exit 1
539-
540-echo -n "libtoolize... "
541-if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then
542- echo "using glibtoolize"
543- glibtoolize --automake --copy --force || exit 1
544-
545-elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then
546- echo "using libtoolize"
547- libtoolize --automake --copy --force || exit 1
548-
549-else
550- echo "libtoolize nor glibtoolize not found"
551- exit 1
552-fi
553-
554-echo automake...
555-(automake --version) < /dev/null > /dev/null 2>&1 || {
556- echo automake not found
557- exit 1
558-}
559-
560-automake --add-missing --copy --foreign || exit 1
561-
562-echo autoconf...
563-(autoconf --version) < /dev/null > /dev/null 2>&1 || {
564- echo autoconf not found
565- exit 1
566-}
567-
568-autoconf || exit 1
569-
570-echo ready to configure
571-
572-exit 0
573diff --git a/configure.ac b/configure.ac
574index a4f051e4..453e2936 100644
575--- a/configure.ac
576+++ b/configure.ac
577@@ -1,10 +1,14 @@
578-AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com)
579+AC_INIT([[libtorrent]],[[0.13.8]],[[sundell.software@gmail.com]])
580
581-LT_INIT([disable-static])
582+AC_CONFIG_HEADERS([config.h])
583+AC_CONFIG_MACRO_DIRS([scripts])
584+AM_INIT_AUTOMAKE([serial-tests subdir-objects foreign])
585+
586+LT_INIT([[disable-static]])
587
588 dnl Find a better way to do this
589-AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id)
590-AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT)
591+AC_DEFINE([[PEER_NAME]], [["-lt0D80-"]], [[Identifier that is part of the default peer id.]])
592+AC_DEFINE([[PEER_VERSION]], [["lt\x0D\x80"]], [[4 byte client and version identifier for DHT.]])
593
594 LIBTORRENT_CURRENT=21
595 LIBTORRENT_REVISION=0
596@@ -17,9 +21,6 @@ AC_SUBST(LIBTORRENT_CURRENT)
597 AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO)
598 AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO)
599
600-AM_INIT_AUTOMAKE([serial-tests subdir-objects])
601-AC_CONFIG_HEADERS(config.h)
602-
603 AC_PROG_CXX
604 AC_SYS_LARGEFILE
605
606@@ -29,14 +30,14 @@ AC_C_BIGENDIAN(
607 AC_MSG_ERROR([Could not determine endianness])
608 )
609
610+AX_CXX_COMPILE_STDCXX(14, noext, mandatory)
611+
612 RAK_CHECK_CFLAGS
613 RAK_CHECK_CXXFLAGS
614 RAK_ENABLE_DEBUG
615 RAK_ENABLE_EXTRA_DEBUG
616 RAK_ENABLE_WERROR
617
618-RAK_CHECK_CXX11
619-
620 TORRENT_ENABLE_ALIGNED
621 TORRENT_ENABLE_INTERRUPT_SOCKET
622
623@@ -55,7 +56,7 @@ TORRENT_WITHOUT_STATFS
624 TORRENT_WITH_INOTIFY
625
626 AC_ARG_ENABLE(attribute-visibility,
627- AC_HELP_STRING([--disable-attribute-visibility], [disable symbol visibility attribute [[default=enable]]]),
628+ AS_HELP_STRING([--disable-attribute-visibility],[disable symbol visibility attribute [[default=enable]]]),
629 [
630 if test "$enableval" = "yes"; then
631 CC_ATTRIBUTE_VISIBILITY
632@@ -65,7 +66,7 @@ AC_ARG_ENABLE(attribute-visibility,
633 ])
634
635 AC_ARG_ENABLE(execinfo,
636- AC_HELP_STRING([--disable-execinfo], [disable libexecinfo [[default=enable]]]),
637+ AS_HELP_STRING([--disable-execinfo],[disable libexecinfo [[default=enable]]]),
638 [
639 if test "$enableval" = "yes"; then
640 AX_EXECINFO
641@@ -109,12 +110,13 @@ CC_ATTRIBUTE_UNUSED(
642 AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
643 )
644
645-AC_OUTPUT([
646+AC_CONFIG_FILES([
647 libtorrent.pc
648 Makefile
649 src/Makefile
650 src/torrent/Makefile
651- test/Makefile
652- test/torrent/net/Makefile
653- test/net/Makefile
654+ test/Makefile
655+ test/torrent/net/Makefile
656+ test/net/Makefile
657 ])
658+AC_OUTPUT
659diff --git a/scripts/ax_check_zlib.m4 b/scripts/ax_check_zlib.m4
660old mode 100644
661new mode 100755
662index ae5705f6..1a168430
663--- a/scripts/ax_check_zlib.m4
664+++ b/scripts/ax_check_zlib.m4
665@@ -1,5 +1,5 @@
666 # ===========================================================================
667-# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
668+# https://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
669 # ===========================================================================
670 #
671 # SYNOPSIS
672@@ -47,7 +47,7 @@
673 # Public License for more details.
674 #
675 # You should have received a copy of the GNU General Public License along
676-# with this program. If not, see <http://www.gnu.org/licenses/>.
677+# with this program. If not, see <https://www.gnu.org/licenses/>.
678 #
679 # As a special exception, the respective Autoconf Macro's copyright owner
680 # gives unlimited permission to copy, distribute and modify the configure
681@@ -62,7 +62,7 @@
682 # modified version of the Autoconf Macro, you may extend this special
683 # exception to the GPL to apply to your modified version as well.
684
685-#serial 14
686+#serial 16
687
688 AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB])
689 AC_DEFUN([AX_CHECK_ZLIB],
690@@ -108,11 +108,10 @@ then
691 LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
692 CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
693 fi
694- AC_LANG_SAVE
695- AC_LANG_C
696+ AC_LANG_PUSH([C])
697 AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no])
698 AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no])
699- AC_LANG_RESTORE
700+ AC_LANG_POP([C])
701 if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes"
702 then
703 #
704diff --git a/scripts/ax_cxx_compile_stdcxx.m4 b/scripts/ax_cxx_compile_stdcxx.m4
705new file mode 100755
706index 00000000..9413da62
707--- /dev/null
708+++ b/scripts/ax_cxx_compile_stdcxx.m4
709@@ -0,0 +1,962 @@
710+# ===========================================================================
711+# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
712+# ===========================================================================
713+#
714+# SYNOPSIS
715+#
716+# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
717+#
718+# DESCRIPTION
719+#
720+# Check for baseline language coverage in the compiler for the specified
721+# version of the C++ standard. If necessary, add switches to CXX and
722+# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
723+# or '14' (for the C++14 standard).
724+#
725+# The second argument, if specified, indicates whether you insist on an
726+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
727+# -std=c++11). If neither is specified, you get whatever works, with
728+# preference for no added switch, and then for an extended mode.
729+#
730+# The third argument, if specified 'mandatory' or if left unspecified,
731+# indicates that baseline support for the specified C++ standard is
732+# required and that the macro should error out if no mode with that
733+# support is found. If specified 'optional', then configuration proceeds
734+# regardless, after defining HAVE_CXX${VERSION} if and only if a
735+# supporting mode is found.
736+#
737+# LICENSE
738+#
739+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
740+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
741+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
742+# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
743+# Copyright (c) 2015 Paul Norman <penorman@mac.com>
744+# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
745+# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
746+# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
747+# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
748+#
749+# Copying and distribution of this file, with or without modification, are
750+# permitted in any medium without royalty provided the copyright notice
751+# and this notice are preserved. This file is offered as-is, without any
752+# warranty.
753+
754+#serial 12
755+
756+dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
757+dnl (serial version number 13).
758+
759+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
760+ m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
761+ [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
762+ [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
763+ [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
764+ m4_if([$2], [], [],
765+ [$2], [ext], [],
766+ [$2], [noext], [],
767+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
768+ m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
769+ [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
770+ [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
771+ [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
772+ AC_LANG_PUSH([C++])dnl
773+ ac_success=no
774+
775+ m4_if([$2], [], [dnl
776+ AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
777+ ax_cv_cxx_compile_cxx$1,
778+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
779+ [ax_cv_cxx_compile_cxx$1=yes],
780+ [ax_cv_cxx_compile_cxx$1=no])])
781+ if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
782+ ac_success=yes
783+ fi])
784+
785+ m4_if([$2], [noext], [], [dnl
786+ if test x$ac_success = xno; then
787+ for alternative in ${ax_cxx_compile_alternatives}; do
788+ switch="-std=gnu++${alternative}"
789+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
790+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
791+ $cachevar,
792+ [ac_save_CXX="$CXX"
793+ CXX="$CXX $switch"
794+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
795+ [eval $cachevar=yes],
796+ [eval $cachevar=no])
797+ CXX="$ac_save_CXX"])
798+ if eval test x\$$cachevar = xyes; then
799+ CXX="$CXX $switch"
800+ if test -n "$CXXCPP" ; then
801+ CXXCPP="$CXXCPP $switch"
802+ fi
803+ ac_success=yes
804+ break
805+ fi
806+ done
807+ fi])
808+
809+ m4_if([$2], [ext], [], [dnl
810+ if test x$ac_success = xno; then
811+ dnl HP's aCC needs +std=c++11 according to:
812+ dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
813+ dnl Cray's crayCC needs "-h std=c++11"
814+ for alternative in ${ax_cxx_compile_alternatives}; do
815+ for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
816+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
817+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
818+ $cachevar,
819+ [ac_save_CXX="$CXX"
820+ CXX="$CXX $switch"
821+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
822+ [eval $cachevar=yes],
823+ [eval $cachevar=no])
824+ CXX="$ac_save_CXX"])
825+ if eval test x\$$cachevar = xyes; then
826+ CXX="$CXX $switch"
827+ if test -n "$CXXCPP" ; then
828+ CXXCPP="$CXXCPP $switch"
829+ fi
830+ ac_success=yes
831+ break
832+ fi
833+ done
834+ if test x$ac_success = xyes; then
835+ break
836+ fi
837+ done
838+ fi])
839+ AC_LANG_POP([C++])
840+ if test x$ax_cxx_compile_cxx$1_required = xtrue; then
841+ if test x$ac_success = xno; then
842+ AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
843+ fi
844+ fi
845+ if test x$ac_success = xno; then
846+ HAVE_CXX$1=0
847+ AC_MSG_NOTICE([No compiler with C++$1 support was found])
848+ else
849+ HAVE_CXX$1=1
850+ AC_DEFINE(HAVE_CXX$1,1,
851+ [define if the compiler supports basic C++$1 syntax])
852+ fi
853+ AC_SUBST(HAVE_CXX$1)
854+])
855+
856+
857+dnl Test body for checking C++11 support
858+
859+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
860+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
861+)
862+
863+
864+dnl Test body for checking C++14 support
865+
866+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
867+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
868+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
869+)
870+
871+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
872+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
873+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
874+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
875+)
876+
877+dnl Tests for new features in C++11
878+
879+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
880+
881+// If the compiler admits that it is not ready for C++11, why torture it?
882+// Hopefully, this will speed up the test.
883+
884+#ifndef __cplusplus
885+
886+#error "This is not a C++ compiler"
887+
888+#elif __cplusplus < 201103L
889+
890+#error "This is not a C++11 compiler"
891+
892+#else
893+
894+namespace cxx11
895+{
896+
897+ namespace test_static_assert
898+ {
899+
900+ template <typename T>
901+ struct check
902+ {
903+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
904+ };
905+
906+ }
907+
908+ namespace test_final_override
909+ {
910+
911+ struct Base
912+ {
913+ virtual ~Base() {}
914+ virtual void f() {}
915+ };
916+
917+ struct Derived : public Base
918+ {
919+ virtual ~Derived() override {}
920+ virtual void f() override {}
921+ };
922+
923+ }
924+
925+ namespace test_double_right_angle_brackets
926+ {
927+
928+ template < typename T >
929+ struct check {};
930+
931+ typedef check<void> single_type;
932+ typedef check<check<void>> double_type;
933+ typedef check<check<check<void>>> triple_type;
934+ typedef check<check<check<check<void>>>> quadruple_type;
935+
936+ }
937+
938+ namespace test_decltype
939+ {
940+
941+ int
942+ f()
943+ {
944+ int a = 1;
945+ decltype(a) b = 2;
946+ return a + b;
947+ }
948+
949+ }
950+
951+ namespace test_type_deduction
952+ {
953+
954+ template < typename T1, typename T2 >
955+ struct is_same
956+ {
957+ static const bool value = false;
958+ };
959+
960+ template < typename T >
961+ struct is_same<T, T>
962+ {
963+ static const bool value = true;
964+ };
965+
966+ template < typename T1, typename T2 >
967+ auto
968+ add(T1 a1, T2 a2) -> decltype(a1 + a2)
969+ {
970+ return a1 + a2;
971+ }
972+
973+ int
974+ test(const int c, volatile int v)
975+ {
976+ static_assert(is_same<int, decltype(0)>::value == true, "");
977+ static_assert(is_same<int, decltype(c)>::value == false, "");
978+ static_assert(is_same<int, decltype(v)>::value == false, "");
979+ auto ac = c;
980+ auto av = v;
981+ auto sumi = ac + av + 'x';
982+ auto sumf = ac + av + 1.0;
983+ static_assert(is_same<int, decltype(ac)>::value == true, "");
984+ static_assert(is_same<int, decltype(av)>::value == true, "");
985+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
986+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
987+ static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
988+ return (sumf > 0.0) ? sumi : add(c, v);
989+ }
990+
991+ }
992+
993+ namespace test_noexcept
994+ {
995+
996+ int f() { return 0; }
997+ int g() noexcept { return 0; }
998+
999+ static_assert(noexcept(f()) == false, "");
1000+ static_assert(noexcept(g()) == true, "");
1001+
1002+ }
1003+
1004+ namespace test_constexpr
1005+ {
1006+
1007+ template < typename CharT >
1008+ unsigned long constexpr
1009+ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
1010+ {
1011+ return *s ? strlen_c_r(s + 1, acc + 1) : acc;
1012+ }
1013+
1014+ template < typename CharT >
1015+ unsigned long constexpr
1016+ strlen_c(const CharT *const s) noexcept
1017+ {
1018+ return strlen_c_r(s, 0UL);
1019+ }
1020+
1021+ static_assert(strlen_c("") == 0UL, "");
1022+ static_assert(strlen_c("1") == 1UL, "");
1023+ static_assert(strlen_c("example") == 7UL, "");
1024+ static_assert(strlen_c("another\0example") == 7UL, "");
1025+
1026+ }
1027+
1028+ namespace test_rvalue_references
1029+ {
1030+
1031+ template < int N >
1032+ struct answer
1033+ {
1034+ static constexpr int value = N;
1035+ };
1036+
1037+ answer<1> f(int&) { return answer<1>(); }
1038+ answer<2> f(const int&) { return answer<2>(); }
1039+ answer<3> f(int&&) { return answer<3>(); }
1040+
1041+ void
1042+ test()
1043+ {
1044+ int i = 0;
1045+ const int c = 0;
1046+ static_assert(decltype(f(i))::value == 1, "");
1047+ static_assert(decltype(f(c))::value == 2, "");
1048+ static_assert(decltype(f(0))::value == 3, "");
1049+ }
1050+
1051+ }
1052+
1053+ namespace test_uniform_initialization
1054+ {
1055+
1056+ struct test
1057+ {
1058+ static const int zero {};
1059+ static const int one {1};
1060+ };
1061+
1062+ static_assert(test::zero == 0, "");
1063+ static_assert(test::one == 1, "");
1064+
1065+ }
1066+
1067+ namespace test_lambdas
1068+ {
1069+
1070+ void
1071+ test1()
1072+ {
1073+ auto lambda1 = [](){};
1074+ auto lambda2 = lambda1;
1075+ lambda1();
1076+ lambda2();
1077+ }
1078+
1079+ int
1080+ test2()
1081+ {
1082+ auto a = [](int i, int j){ return i + j; }(1, 2);
1083+ auto b = []() -> int { return '0'; }();
1084+ auto c = [=](){ return a + b; }();
1085+ auto d = [&](){ return c; }();
1086+ auto e = [a, &b](int x) mutable {
1087+ const auto identity = [](int y){ return y; };
1088+ for (auto i = 0; i < a; ++i)
1089+ a += b--;
1090+ return x + identity(a + b);
1091+ }(0);
1092+ return a + b + c + d + e;
1093+ }
1094+
1095+ int
1096+ test3()
1097+ {
1098+ const auto nullary = [](){ return 0; };
1099+ const auto unary = [](int x){ return x; };
1100+ using nullary_t = decltype(nullary);
1101+ using unary_t = decltype(unary);
1102+ const auto higher1st = [](nullary_t f){ return f(); };
1103+ const auto higher2nd = [unary](nullary_t f1){
1104+ return [unary, f1](unary_t f2){ return f2(unary(f1())); };
1105+ };
1106+ return higher1st(nullary) + higher2nd(nullary)(unary);
1107+ }
1108+
1109+ }
1110+
1111+ namespace test_variadic_templates
1112+ {
1113+
1114+ template <int...>
1115+ struct sum;
1116+
1117+ template <int N0, int... N1toN>
1118+ struct sum<N0, N1toN...>
1119+ {
1120+ static constexpr auto value = N0 + sum<N1toN...>::value;
1121+ };
1122+
1123+ template <>
1124+ struct sum<>
1125+ {
1126+ static constexpr auto value = 0;
1127+ };
1128+
1129+ static_assert(sum<>::value == 0, "");
1130+ static_assert(sum<1>::value == 1, "");
1131+ static_assert(sum<23>::value == 23, "");
1132+ static_assert(sum<1, 2>::value == 3, "");
1133+ static_assert(sum<5, 5, 11>::value == 21, "");
1134+ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
1135+
1136+ }
1137+
1138+ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
1139+ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
1140+ // because of this.
1141+ namespace test_template_alias_sfinae
1142+ {
1143+
1144+ struct foo {};
1145+
1146+ template<typename T>
1147+ using member = typename T::member_type;
1148+
1149+ template<typename T>
1150+ void func(...) {}
1151+
1152+ template<typename T>
1153+ void func(member<T>*) {}
1154+
1155+ void test();
1156+
1157+ void test() { func<foo>(0); }
1158+
1159+ }
1160+
1161+} // namespace cxx11
1162+
1163+#endif // __cplusplus >= 201103L
1164+
1165+]])
1166+
1167+
1168+dnl Tests for new features in C++14
1169+
1170+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
1171+
1172+// If the compiler admits that it is not ready for C++14, why torture it?
1173+// Hopefully, this will speed up the test.
1174+
1175+#ifndef __cplusplus
1176+
1177+#error "This is not a C++ compiler"
1178+
1179+#elif __cplusplus < 201402L
1180+
1181+#error "This is not a C++14 compiler"
1182+
1183+#else
1184+
1185+namespace cxx14
1186+{
1187+
1188+ namespace test_polymorphic_lambdas
1189+ {
1190+
1191+ int
1192+ test()
1193+ {
1194+ const auto lambda = [](auto&&... args){
1195+ const auto istiny = [](auto x){
1196+ return (sizeof(x) == 1UL) ? 1 : 0;
1197+ };
1198+ const int aretiny[] = { istiny(args)... };
1199+ return aretiny[0];
1200+ };
1201+ return lambda(1, 1L, 1.0f, '1');
1202+ }
1203+
1204+ }
1205+
1206+ namespace test_binary_literals
1207+ {
1208+
1209+ constexpr auto ivii = 0b0000000000101010;
1210+ static_assert(ivii == 42, "wrong value");
1211+
1212+ }
1213+
1214+ namespace test_generalized_constexpr
1215+ {
1216+
1217+ template < typename CharT >
1218+ constexpr unsigned long
1219+ strlen_c(const CharT *const s) noexcept
1220+ {
1221+ auto length = 0UL;
1222+ for (auto p = s; *p; ++p)
1223+ ++length;
1224+ return length;
1225+ }
1226+
1227+ static_assert(strlen_c("") == 0UL, "");
1228+ static_assert(strlen_c("x") == 1UL, "");
1229+ static_assert(strlen_c("test") == 4UL, "");
1230+ static_assert(strlen_c("another\0test") == 7UL, "");
1231+
1232+ }
1233+
1234+ namespace test_lambda_init_capture
1235+ {
1236+
1237+ int
1238+ test()
1239+ {
1240+ auto x = 0;
1241+ const auto lambda1 = [a = x](int b){ return a + b; };
1242+ const auto lambda2 = [a = lambda1(x)](){ return a; };
1243+ return lambda2();
1244+ }
1245+
1246+ }
1247+
1248+ namespace test_digit_separators
1249+ {
1250+
1251+ constexpr auto ten_million = 100'000'000;
1252+ static_assert(ten_million == 100000000, "");
1253+
1254+ }
1255+
1256+ namespace test_return_type_deduction
1257+ {
1258+
1259+ auto f(int& x) { return x; }
1260+ decltype(auto) g(int& x) { return x; }
1261+
1262+ template < typename T1, typename T2 >
1263+ struct is_same
1264+ {
1265+ static constexpr auto value = false;
1266+ };
1267+
1268+ template < typename T >
1269+ struct is_same<T, T>
1270+ {
1271+ static constexpr auto value = true;
1272+ };
1273+
1274+ int
1275+ test()
1276+ {
1277+ auto x = 0;
1278+ static_assert(is_same<int, decltype(f(x))>::value, "");
1279+ static_assert(is_same<int&, decltype(g(x))>::value, "");
1280+ return x;
1281+ }
1282+
1283+ }
1284+
1285+} // namespace cxx14
1286+
1287+#endif // __cplusplus >= 201402L
1288+
1289+]])
1290+
1291+
1292+dnl Tests for new features in C++17
1293+
1294+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
1295+
1296+// If the compiler admits that it is not ready for C++17, why torture it?
1297+// Hopefully, this will speed up the test.
1298+
1299+#ifndef __cplusplus
1300+
1301+#error "This is not a C++ compiler"
1302+
1303+#elif __cplusplus < 201703L
1304+
1305+#error "This is not a C++17 compiler"
1306+
1307+#else
1308+
1309+#include <initializer_list>
1310+#include <utility>
1311+#include <type_traits>
1312+
1313+namespace cxx17
1314+{
1315+
1316+ namespace test_constexpr_lambdas
1317+ {
1318+
1319+ constexpr int foo = [](){return 42;}();
1320+
1321+ }
1322+
1323+ namespace test::nested_namespace::definitions
1324+ {
1325+
1326+ }
1327+
1328+ namespace test_fold_expression
1329+ {
1330+
1331+ template<typename... Args>
1332+ int multiply(Args... args)
1333+ {
1334+ return (args * ... * 1);
1335+ }
1336+
1337+ template<typename... Args>
1338+ bool all(Args... args)
1339+ {
1340+ return (args && ...);
1341+ }
1342+
1343+ }
1344+
1345+ namespace test_extended_static_assert
1346+ {
1347+
1348+ static_assert (true);
1349+
1350+ }
1351+
1352+ namespace test_auto_brace_init_list
1353+ {
1354+
1355+ auto foo = {5};
1356+ auto bar {5};
1357+
1358+ static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
1359+ static_assert(std::is_same<int, decltype(bar)>::value);
1360+ }
1361+
1362+ namespace test_typename_in_template_template_parameter
1363+ {
1364+
1365+ template<template<typename> typename X> struct D;
1366+
1367+ }
1368+
1369+ namespace test_fallthrough_nodiscard_maybe_unused_attributes
1370+ {
1371+
1372+ int f1()
1373+ {
1374+ return 42;
1375+ }
1376+
1377+ [[nodiscard]] int f2()
1378+ {
1379+ [[maybe_unused]] auto unused = f1();
1380+
1381+ switch (f1())
1382+ {
1383+ case 17:
1384+ f1();
1385+ [[fallthrough]];
1386+ case 42:
1387+ f1();
1388+ }
1389+ return f1();
1390+ }
1391+
1392+ }
1393+
1394+ namespace test_extended_aggregate_initialization
1395+ {
1396+
1397+ struct base1
1398+ {
1399+ int b1, b2 = 42;
1400+ };
1401+
1402+ struct base2
1403+ {
1404+ base2() {
1405+ b3 = 42;
1406+ }
1407+ int b3;
1408+ };
1409+
1410+ struct derived : base1, base2
1411+ {
1412+ int d;
1413+ };
1414+
1415+ derived d1 {{1, 2}, {}, 4}; // full initialization
1416+ derived d2 {{}, {}, 4}; // value-initialized bases
1417+
1418+ }
1419+
1420+ namespace test_general_range_based_for_loop
1421+ {
1422+
1423+ struct iter
1424+ {
1425+ int i;
1426+
1427+ int& operator* ()
1428+ {
1429+ return i;
1430+ }
1431+
1432+ const int& operator* () const
1433+ {
1434+ return i;
1435+ }
1436+
1437+ iter& operator++()
1438+ {
1439+ ++i;
1440+ return *this;
1441+ }
1442+ };
1443+
1444+ struct sentinel
1445+ {
1446+ int i;
1447+ };
1448+
1449+ bool operator== (const iter& i, const sentinel& s)
1450+ {
1451+ return i.i == s.i;
1452+ }
1453+
1454+ bool operator!= (const iter& i, const sentinel& s)
1455+ {
1456+ return !(i == s);
1457+ }
1458+
1459+ struct range
1460+ {
1461+ iter begin() const
1462+ {
1463+ return {0};
1464+ }
1465+
1466+ sentinel end() const
1467+ {
1468+ return {5};
1469+ }
1470+ };
1471+
1472+ void f()
1473+ {
1474+ range r {};
1475+
1476+ for (auto i : r)
1477+ {
1478+ [[maybe_unused]] auto v = i;
1479+ }
1480+ }
1481+
1482+ }
1483+
1484+ namespace test_lambda_capture_asterisk_this_by_value
1485+ {
1486+
1487+ struct t
1488+ {
1489+ int i;
1490+ int foo()
1491+ {
1492+ return [*this]()
1493+ {
1494+ return i;
1495+ }();
1496+ }
1497+ };
1498+
1499+ }
1500+
1501+ namespace test_enum_class_construction
1502+ {
1503+
1504+ enum class byte : unsigned char
1505+ {};
1506+
1507+ byte foo {42};
1508+
1509+ }
1510+
1511+ namespace test_constexpr_if
1512+ {
1513+
1514+ template <bool cond>
1515+ int f ()
1516+ {
1517+ if constexpr(cond)
1518+ {
1519+ return 13;
1520+ }
1521+ else
1522+ {
1523+ return 42;
1524+ }
1525+ }
1526+
1527+ }
1528+
1529+ namespace test_selection_statement_with_initializer
1530+ {
1531+
1532+ int f()
1533+ {
1534+ return 13;
1535+ }
1536+
1537+ int f2()
1538+ {
1539+ if (auto i = f(); i > 0)
1540+ {
1541+ return 3;
1542+ }
1543+
1544+ switch (auto i = f(); i + 4)
1545+ {
1546+ case 17:
1547+ return 2;
1548+
1549+ default:
1550+ return 1;
1551+ }
1552+ }
1553+
1554+ }
1555+
1556+ namespace test_template_argument_deduction_for_class_templates
1557+ {
1558+
1559+ template <typename T1, typename T2>
1560+ struct pair
1561+ {
1562+ pair (T1 p1, T2 p2)
1563+ : m1 {p1},
1564+ m2 {p2}
1565+ {}
1566+
1567+ T1 m1;
1568+ T2 m2;
1569+ };
1570+
1571+ void f()
1572+ {
1573+ [[maybe_unused]] auto p = pair{13, 42u};
1574+ }
1575+
1576+ }
1577+
1578+ namespace test_non_type_auto_template_parameters
1579+ {
1580+
1581+ template <auto n>
1582+ struct B
1583+ {};
1584+
1585+ B<5> b1;
1586+ B<'a'> b2;
1587+
1588+ }
1589+
1590+ namespace test_structured_bindings
1591+ {
1592+
1593+ int arr[2] = { 1, 2 };
1594+ std::pair<int, int> pr = { 1, 2 };
1595+
1596+ auto f1() -> int(&)[2]
1597+ {
1598+ return arr;
1599+ }
1600+
1601+ auto f2() -> std::pair<int, int>&
1602+ {
1603+ return pr;
1604+ }
1605+
1606+ struct S
1607+ {
1608+ int x1 : 2;
1609+ volatile double y1;
1610+ };
1611+
1612+ S f3()
1613+ {
1614+ return {};
1615+ }
1616+
1617+ auto [ x1, y1 ] = f1();
1618+ auto& [ xr1, yr1 ] = f1();
1619+ auto [ x2, y2 ] = f2();
1620+ auto& [ xr2, yr2 ] = f2();
1621+ const auto [ x3, y3 ] = f3();
1622+
1623+ }
1624+
1625+ namespace test_exception_spec_type_system
1626+ {
1627+
1628+ struct Good {};
1629+ struct Bad {};
1630+
1631+ void g1() noexcept;
1632+ void g2();
1633+
1634+ template<typename T>
1635+ Bad
1636+ f(T*, T*);
1637+
1638+ template<typename T1, typename T2>
1639+ Good
1640+ f(T1*, T2*);
1641+
1642+ static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
1643+
1644+ }
1645+
1646+ namespace test_inline_variables
1647+ {
1648+
1649+ template<class T> void f(T)
1650+ {}
1651+
1652+ template<class T> inline T g(T)
1653+ {
1654+ return T{};
1655+ }
1656+
1657+ template<> inline void f<>(int)
1658+ {}
1659+
1660+ template<> int g<>(int)
1661+ {
1662+ return 5;
1663+ }
1664+
1665+ }
1666+
1667+} // namespace cxx17
1668+
1669+#endif // __cplusplus < 201703L
1670+
1671+]])
1672diff --git a/scripts/ax_cxx_compile_stdcxx_0x.m4 b/scripts/ax_cxx_compile_stdcxx_0x.m4
1673deleted file mode 100644
1674index 5ff134a6..00000000
1675--- a/scripts/ax_cxx_compile_stdcxx_0x.m4
1676+++ /dev/null
1677@@ -1,106 +0,0 @@
1678-# ============================================================================
1679-# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html
1680-# ============================================================================
1681-#
1682-# SYNOPSIS
1683-#
1684-# AX_CXX_COMPILE_STDCXX_0X
1685-#
1686-# DESCRIPTION
1687-#
1688-# Check for baseline language coverage in the compiler for the C++0x
1689-# standard.
1690-#
1691-# LICENSE
1692-#
1693-# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
1694-#
1695-# Copying and distribution of this file, with or without modification, are
1696-# permitted in any medium without royalty provided the copyright notice
1697-# and this notice are preserved. This file is offered as-is, without any
1698-# warranty.
1699-
1700-#serial 7 (+1)
1701-
1702-AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X])
1703-AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [
1704- AC_CACHE_CHECK(if g++ supports C++0x features without additional flags,
1705- ax_cv_cxx_compile_cxx0x_native,
1706- [AC_LANG_SAVE
1707- AC_LANG_CPLUSPLUS
1708- AC_TRY_COMPILE([
1709- template <typename T>
1710- struct check
1711- {
1712- static_assert(sizeof(int) <= sizeof(T), "not big enough");
1713- };
1714-
1715- typedef check<check<bool>> right_angle_brackets;
1716-
1717- int a;
1718- decltype(a) b;
1719-
1720- typedef check<int> check_type;
1721- check_type c;
1722- check_type&& cr = static_cast<check_type&&>(c);],,
1723- ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no)
1724- AC_LANG_RESTORE
1725- ])
1726-
1727- AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x,
1728- ax_cv_cxx_compile_cxx0x_cxx,
1729- [AC_LANG_SAVE
1730- AC_LANG_CPLUSPLUS
1731- ac_save_CXXFLAGS="$CXXFLAGS"
1732- CXXFLAGS="$CXXFLAGS -std=c++0x"
1733- AC_TRY_COMPILE([
1734- template <typename T>
1735- struct check
1736- {
1737- static_assert(sizeof(int) <= sizeof(T), "not big enough");
1738- };
1739-
1740- typedef check<check<bool>> right_angle_brackets;
1741-
1742- int a;
1743- decltype(a) b;
1744-
1745- typedef check<int> check_type;
1746- check_type c;
1747- check_type&& cr = static_cast<check_type&&>(c);],,
1748- ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no)
1749- CXXFLAGS="$ac_save_CXXFLAGS"
1750- AC_LANG_RESTORE
1751- ])
1752-
1753- AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x,
1754- ax_cv_cxx_compile_cxx0x_gxx,
1755- [AC_LANG_SAVE
1756- AC_LANG_CPLUSPLUS
1757- ac_save_CXXFLAGS="$CXXFLAGS"
1758- CXXFLAGS="$CXXFLAGS -std=gnu++0x"
1759- AC_TRY_COMPILE([
1760- template <typename T>
1761- struct check
1762- {
1763- static_assert(sizeof(int) <= sizeof(T), "not big enough");
1764- };
1765-
1766- typedef check<check<bool>> right_angle_brackets;
1767-
1768- int a;
1769- decltype(a) b;
1770-
1771- typedef check<int> check_type;
1772- check_type c;
1773- check_type&& cr = static_cast<check_type&&>(c);],,
1774- ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no)
1775- CXXFLAGS="$ac_save_CXXFLAGS"
1776- AC_LANG_RESTORE
1777- ])
1778-
1779- if test "$ax_cv_cxx_compile_cxx0x_cxx" = yes; then
1780- AC_DEFINE(HAVE_STDCXX_0X,, [Define if compiler supports C++0x features.])
1781- CXXFLAGS="$CXXFLAGS -std=c++0x"
1782- fi
1783-])
1784diff --git a/scripts/ax_cxx_compile_stdcxx_11.m4 b/scripts/ax_cxx_compile_stdcxx_11.m4
1785deleted file mode 100644
1786index 5cf70eb6..00000000
1787--- a/scripts/ax_cxx_compile_stdcxx_11.m4
1788+++ /dev/null
1789@@ -1,147 +0,0 @@
1790-# ============================================================================
1791-# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
1792-# ============================================================================
1793-#
1794-# SYNOPSIS
1795-#
1796-# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
1797-#
1798-# DESCRIPTION
1799-#
1800-# Check for baseline language coverage in the compiler for the C++11
1801-# standard; if necessary, add switches to CXXFLAGS to enable support.
1802-#
1803-# The first argument, if specified, indicates whether you insist on an
1804-# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
1805-# -std=c++11). If neither is specified, you get whatever works, with
1806-# preference for an extended mode.
1807-#
1808-# The second argument, if specified 'mandatory' or if left unspecified,
1809-# indicates that baseline C++11 support is required and that the macro
1810-# should error out if no mode with that support is found. If specified
1811-# 'optional', then configuration proceeds regardless, after defining
1812-# HAVE_CXX11 if and only if a supporting mode is found.
1813-#
1814-# LICENSE
1815-#
1816-# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
1817-# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
1818-# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
1819-# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
1820-# Copyright (c) 2014 Jari Sundell <sundell.software@gmail.com>
1821-#
1822-# Copying and distribution of this file, with or without modification, are
1823-# permitted in any medium without royalty provided the copyright notice
1824-# and this notice are preserved. This file is offered as-is, without any
1825-# warranty.
1826-
1827-#serial 5
1828-
1829-m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
1830- template <typename T>
1831- struct check
1832- {
1833- static_assert(sizeof(int) <= sizeof(T), "not big enough");
1834- };
1835-
1836- struct Base {
1837- virtual void f() {}
1838- };
1839- struct Child : public Base {
1840- virtual void f() override {}
1841- };
1842-
1843- typedef check<check<bool>> right_angle_brackets;
1844-
1845- int a;
1846- decltype(a) b;
1847-
1848- typedef check<int> check_type;
1849- check_type c;
1850- check_type&& cr = static_cast<check_type&&>(c);
1851-
1852- auto d = a;
1853- auto l = [](){};
1854-
1855- void unused() {
1856- l();
1857- }
1858-]])
1859-
1860-AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
1861- m4_if([$1], [], [],
1862- [$1], [ext], [],
1863- [$1], [noext], [],
1864- [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
1865- m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
1866- [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
1867- [$2], [optional], [ax_cxx_compile_cxx11_required=false],
1868- [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
1869- AC_LANG_PUSH([C++])dnl
1870- ac_success=no
1871- AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
1872- ax_cv_cxx_compile_cxx11,
1873- [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
1874- [ax_cv_cxx_compile_cxx11=yes],
1875- [ax_cv_cxx_compile_cxx11=no])])
1876- if test x$ax_cv_cxx_compile_cxx11 = xyes; then
1877- ac_success=yes
1878- fi
1879-
1880- m4_if([$1], [noext], [], [dnl
1881- if test x$ac_success = xno; then
1882- for switch in -std=gnu++11 -std=gnu++0x; do
1883- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
1884- AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
1885- $cachevar,
1886- [ac_save_CXXFLAGS="$CXXFLAGS"
1887- CXXFLAGS="$CXXFLAGS $switch"
1888- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
1889- [eval $cachevar=yes],
1890- [eval $cachevar=no])
1891- CXXFLAGS="$ac_save_CXXFLAGS"])
1892- if eval test x\$$cachevar = xyes; then
1893- CXXFLAGS="$CXXFLAGS $switch"
1894- ac_success=yes
1895- break
1896- fi
1897- done
1898- fi])
1899-
1900- m4_if([$1], [ext], [], [dnl
1901- if test x$ac_success = xno; then
1902- for switch in -std=c++11 -std=c++0x; do
1903- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
1904- AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
1905- $cachevar,
1906- [ac_save_CXXFLAGS="$CXXFLAGS"
1907- CXXFLAGS="$CXXFLAGS $switch"
1908- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
1909- [eval $cachevar=yes],
1910- [eval $cachevar=no])
1911- CXXFLAGS="$ac_save_CXXFLAGS"])
1912- if eval test x\$$cachevar = xyes; then
1913- CXXFLAGS="$CXXFLAGS $switch"
1914- ac_success=yes
1915- break
1916- fi
1917- done
1918- fi])
1919- AC_LANG_POP([C++])
1920- if test x$ax_cxx_compile_cxx11_required = xtrue; then
1921- if test x$ac_success = xno; then
1922- AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
1923- fi
1924- else
1925- if test x$ac_success = xno; then
1926- HAVE_CXX11=0
1927- AC_MSG_NOTICE([No compiler with C++11 support was found])
1928- else
1929- HAVE_CXX11=1
1930- AC_DEFINE(HAVE_CXX11,1,
1931- [define if the compiler supports basic C++11 syntax])
1932- fi
1933-
1934- AC_SUBST(HAVE_CXX11)
1935- fi
1936-])
1937diff --git a/scripts/ax_pthread.m4 b/scripts/ax_pthread.m4
1938old mode 100644
1939new mode 100755
1940index 27f2533c..9f35d139
1941--- a/scripts/ax_pthread.m4
1942+++ b/scripts/ax_pthread.m4
1943@@ -1,5 +1,5 @@
1944 # ===========================================================================
1945-# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
1946+# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
1947 # ===========================================================================
1948 #
1949 # SYNOPSIS
1950@@ -14,24 +14,28 @@
1951 # flags that are needed. (The user can also force certain compiler
1952 # flags/libs to be tested by setting these environment variables.)
1953 #
1954-# Also sets PTHREAD_CC to any special C compiler that is needed for
1955-# multi-threaded programs (defaults to the value of CC otherwise). (This
1956-# is necessary on AIX to use the special cc_r compiler alias.)
1957+# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
1958+# needed for multi-threaded programs (defaults to the value of CC
1959+# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
1960+# special cc_r/CC_r compiler alias.)
1961 #
1962 # NOTE: You are assumed to not only compile your program with these flags,
1963-# but also link it with them as well. e.g. you should link with
1964+# but also to link with them as well. For example, you might link with
1965 # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
1966+# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
1967 #
1968-# If you are only building threads programs, you may wish to use these
1969+# If you are only building threaded programs, you may wish to use these
1970 # variables in your default LIBS, CFLAGS, and CC:
1971 #
1972 # LIBS="$PTHREAD_LIBS $LIBS"
1973 # CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
1974+# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
1975 # CC="$PTHREAD_CC"
1976+# CXX="$PTHREAD_CXX"
1977 #
1978 # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
1979-# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
1980-# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
1981+# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
1982+# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
1983 #
1984 # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
1985 # PTHREAD_PRIO_INHERIT symbol is defined when compiling with
1986@@ -55,6 +59,7 @@
1987 #
1988 # Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
1989 # Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
1990+# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
1991 #
1992 # This program is free software: you can redistribute it and/or modify it
1993 # under the terms of the GNU General Public License as published by the
1994@@ -67,7 +72,7 @@
1995 # Public License for more details.
1996 #
1997 # You should have received a copy of the GNU General Public License along
1998-# with this program. If not, see <http://www.gnu.org/licenses/>.
1999+# with this program. If not, see <https://www.gnu.org/licenses/>.
2000 #
2001 # As a special exception, the respective Autoconf Macro's copyright owner
2002 # gives unlimited permission to copy, distribute and modify the configure
2003@@ -82,35 +87,41 @@
2004 # modified version of the Autoconf Macro, you may extend this special
2005 # exception to the GPL to apply to your modified version as well.
2006
2007-#serial 17
2008+#serial 31
2009
2010 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
2011 AC_DEFUN([AX_PTHREAD], [
2012 AC_REQUIRE([AC_CANONICAL_HOST])
2013+AC_REQUIRE([AC_PROG_CC])
2014+AC_REQUIRE([AC_PROG_SED])
2015 AC_LANG_PUSH([C])
2016 ax_pthread_ok=no
2017
2018 # We used to check for pthread.h first, but this fails if pthread.h
2019-# requires special compiler flags (e.g. on True64 or Sequent).
2020+# requires special compiler flags (e.g. on Tru64 or Sequent).
2021 # It gets checked for in the link test anyway.
2022
2023 # First of all, check if the user has set any of the PTHREAD_LIBS,
2024 # etcetera environment variables, and if threads linking works using
2025 # them:
2026-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
2027- save_CFLAGS="$CFLAGS"
2028+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
2029+ ax_pthread_save_CC="$CC"
2030+ ax_pthread_save_CFLAGS="$CFLAGS"
2031+ ax_pthread_save_LIBS="$LIBS"
2032+ AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
2033+ AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
2034 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
2035- save_LIBS="$LIBS"
2036 LIBS="$PTHREAD_LIBS $LIBS"
2037- AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
2038- AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
2039- AC_MSG_RESULT($ax_pthread_ok)
2040- if test x"$ax_pthread_ok" = xno; then
2041+ AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
2042+ AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
2043+ AC_MSG_RESULT([$ax_pthread_ok])
2044+ if test "x$ax_pthread_ok" = "xno"; then
2045 PTHREAD_LIBS=""
2046 PTHREAD_CFLAGS=""
2047 fi
2048- LIBS="$save_LIBS"
2049- CFLAGS="$save_CFLAGS"
2050+ CC="$ax_pthread_save_CC"
2051+ CFLAGS="$ax_pthread_save_CFLAGS"
2052+ LIBS="$ax_pthread_save_LIBS"
2053 fi
2054
2055 # We must check for the threads library under a number of different
2056@@ -118,12 +129,14 @@ fi
2057 # (e.g. DEC) have both -lpthread and -lpthreads, where one of the
2058 # libraries is broken (non-POSIX).
2059
2060-# Create a list of thread flags to try. Items starting with a "-" are
2061-# C compiler flags, and other items are library names, except for "none"
2062-# which indicates that we try without any flags at all, and "pthread-config"
2063-# which is a program returning the flags for the Pth emulation library.
2064+# Create a list of thread flags to try. Items with a "," contain both
2065+# C compiler flags (before ",") and linker flags (after ","). Other items
2066+# starting with a "-" are C compiler flags, and remaining items are
2067+# library names, except for "none" which indicates that we try without
2068+# any flags at all, and "pthread-config" which is a program returning
2069+# the flags for the Pth emulation library.
2070
2071-ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
2072+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
2073
2074 # The ordering *is* (sometimes) important. Some notes on the
2075 # individual items follow:
2076@@ -132,68 +145,163 @@ ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mt
2077 # none: in case threads are in libc; should be tried before -Kthread and
2078 # other compiler flags to prevent continual compiler warnings
2079 # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
2080-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
2081-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
2082-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
2083-# -pthreads: Solaris/gcc
2084-# -mthreads: Mingw32/gcc, Lynx/gcc
2085+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
2086+# (Note: HP C rejects this with "bad form for `-t' option")
2087+# -pthreads: Solaris/gcc (Note: HP C also rejects)
2088 # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
2089-# doesn't hurt to check since this sometimes defines pthreads too;
2090-# also defines -D_REENTRANT)
2091-# ... -mt is also the pthreads flag for HP/aCC
2092+# doesn't hurt to check since this sometimes defines pthreads and
2093+# -D_REENTRANT too), HP C (must be checked before -lpthread, which
2094+# is present but should not be used directly; and before -mthreads,
2095+# because the compiler interprets this as "-mt" + "-hreads")
2096+# -mthreads: Mingw32/gcc, Lynx/gcc
2097 # pthread: Linux, etcetera
2098 # --thread-safe: KAI C++
2099 # pthread-config: use pthread-config program (for GNU Pth library)
2100
2101-case "${host_cpu}-${host_os}" in
2102- *solaris*)
2103+case $host_os in
2104+
2105+ freebsd*)
2106+
2107+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
2108+ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
2109+
2110+ ax_pthread_flags="-kthread lthread $ax_pthread_flags"
2111+ ;;
2112+
2113+ hpux*)
2114+
2115+ # From the cc(1) man page: "[-mt] Sets various -D flags to enable
2116+ # multi-threading and also sets -lpthread."
2117+
2118+ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
2119+ ;;
2120+
2121+ openedition*)
2122+
2123+ # IBM z/OS requires a feature-test macro to be defined in order to
2124+ # enable POSIX threads at all, so give the user a hint if this is
2125+ # not set. (We don't define these ourselves, as they can affect
2126+ # other portions of the system API in unpredictable ways.)
2127+
2128+ AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
2129+ [
2130+# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
2131+ AX_PTHREAD_ZOS_MISSING
2132+# endif
2133+ ],
2134+ [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
2135+ ;;
2136+
2137+ solaris*)
2138
2139 # On Solaris (at least, for some versions), libc contains stubbed
2140 # (non-functional) versions of the pthreads routines, so link-based
2141- # tests will erroneously succeed. (We need to link with -pthreads/-mt/
2142- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
2143- # a function called by this macro, so we could check for that, but
2144- # who knows whether they'll stub that too in a future libc.) So,
2145- # we'll just look for -pthreads and -lpthread first:
2146+ # tests will erroneously succeed. (N.B.: The stubs are missing
2147+ # pthread_cleanup_push, or rather a function called by this macro,
2148+ # so we could check for that, but who knows whether they'll stub
2149+ # that too in a future libc.) So we'll check first for the
2150+ # standard Solaris way of linking pthreads (-mt -lpthread).
2151
2152- ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
2153+ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
2154 ;;
2155+esac
2156
2157- *-darwin*)
2158- ax_pthread_flags="none -pthread $ax_pthread_flags"
2159+# Are we compiling with Clang?
2160+
2161+AC_CACHE_CHECK([whether $CC is Clang],
2162+ [ax_cv_PTHREAD_CLANG],
2163+ [ax_cv_PTHREAD_CLANG=no
2164+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
2165+ if test "x$GCC" = "xyes"; then
2166+ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
2167+ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
2168+# if defined(__clang__) && defined(__llvm__)
2169+ AX_PTHREAD_CC_IS_CLANG
2170+# endif
2171+ ],
2172+ [ax_cv_PTHREAD_CLANG=yes])
2173+ fi
2174+ ])
2175+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
2176+
2177+
2178+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
2179+
2180+# Note that for GCC and Clang -pthread generally implies -lpthread,
2181+# except when -nostdlib is passed.
2182+# This is problematic using libtool to build C++ shared libraries with pthread:
2183+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
2184+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
2185+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
2186+# To solve this, first try -pthread together with -lpthread for GCC
2187+
2188+AS_IF([test "x$GCC" = "xyes"],
2189+ [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
2190+
2191+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
2192+
2193+AS_IF([test "x$ax_pthread_clang" = "xyes"],
2194+ [ax_pthread_flags="-pthread,-lpthread -pthread"])
2195+
2196+
2197+# The presence of a feature test macro requesting re-entrant function
2198+# definitions is, on some systems, a strong hint that pthreads support is
2199+# correctly enabled
2200+
2201+case $host_os in
2202+ darwin* | hpux* | linux* | osf* | solaris*)
2203+ ax_pthread_check_macro="_REENTRANT"
2204+ ;;
2205+
2206+ aix*)
2207+ ax_pthread_check_macro="_THREAD_SAFE"
2208+ ;;
2209+
2210+ *)
2211+ ax_pthread_check_macro="--"
2212 ;;
2213 esac
2214+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
2215+ [ax_pthread_check_cond=0],
2216+ [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
2217+
2218
2219-if test x"$ax_pthread_ok" = xno; then
2220-for flag in $ax_pthread_flags; do
2221+if test "x$ax_pthread_ok" = "xno"; then
2222+for ax_pthread_try_flag in $ax_pthread_flags; do
2223
2224- case $flag in
2225+ case $ax_pthread_try_flag in
2226 none)
2227 AC_MSG_CHECKING([whether pthreads work without any flags])
2228 ;;
2229
2230+ *,*)
2231+ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
2232+ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
2233+ AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
2234+ ;;
2235+
2236 -*)
2237- AC_MSG_CHECKING([whether pthreads work with $flag])
2238- PTHREAD_CFLAGS="$flag"
2239+ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
2240+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
2241 ;;
2242
2243 pthread-config)
2244- AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
2245- if test x"$ax_pthread_config" = xno; then continue; fi
2246+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
2247+ AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
2248 PTHREAD_CFLAGS="`pthread-config --cflags`"
2249 PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
2250 ;;
2251
2252 *)
2253- AC_MSG_CHECKING([for the pthreads library -l$flag])
2254- PTHREAD_LIBS="-l$flag"
2255+ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
2256+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
2257 ;;
2258 esac
2259
2260- save_LIBS="$LIBS"
2261- save_CFLAGS="$CFLAGS"
2262- LIBS="$PTHREAD_LIBS $LIBS"
2263+ ax_pthread_save_CFLAGS="$CFLAGS"
2264+ ax_pthread_save_LIBS="$LIBS"
2265 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
2266+ LIBS="$PTHREAD_LIBS $LIBS"
2267
2268 # Check for various functions. We must include pthread.h,
2269 # since some functions may be macros. (On the Sequent, we
2270@@ -204,8 +312,18 @@ for flag in $ax_pthread_flags; do
2271 # pthread_cleanup_push because it is one of the few pthread
2272 # functions on Solaris that doesn't have a non-functional libc stub.
2273 # We try pthread_create on general principles.
2274+
2275 AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
2276- static void routine(void *a) { a = 0; }
2277+# if $ax_pthread_check_cond
2278+# error "$ax_pthread_check_macro must be defined"
2279+# endif
2280+ static void *some_global = NULL;
2281+ static void routine(void *a)
2282+ {
2283+ /* To avoid any unused-parameter or
2284+ unused-but-set-parameter warning. */
2285+ some_global = a;
2286+ }
2287 static void *start_routine(void *a) { return a; }],
2288 [pthread_t th; pthread_attr_t attr;
2289 pthread_create(&th, 0, start_routine, 0);
2290@@ -213,93 +331,188 @@ for flag in $ax_pthread_flags; do
2291 pthread_attr_init(&attr);
2292 pthread_cleanup_push(routine, 0);
2293 pthread_cleanup_pop(0) /* ; */])],
2294- [ax_pthread_ok=yes],
2295- [])
2296+ [ax_pthread_ok=yes],
2297+ [])
2298
2299- LIBS="$save_LIBS"
2300- CFLAGS="$save_CFLAGS"
2301+ CFLAGS="$ax_pthread_save_CFLAGS"
2302+ LIBS="$ax_pthread_save_LIBS"
2303
2304- AC_MSG_RESULT($ax_pthread_ok)
2305- if test "x$ax_pthread_ok" = xyes; then
2306- break;
2307- fi
2308+ AC_MSG_RESULT([$ax_pthread_ok])
2309+ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
2310
2311 PTHREAD_LIBS=""
2312 PTHREAD_CFLAGS=""
2313 done
2314 fi
2315
2316+
2317+# Clang needs special handling, because older versions handle the -pthread
2318+# option in a rather... idiosyncratic way
2319+
2320+if test "x$ax_pthread_clang" = "xyes"; then
2321+
2322+ # Clang takes -pthread; it has never supported any other flag
2323+
2324+ # (Note 1: This will need to be revisited if a system that Clang
2325+ # supports has POSIX threads in a separate library. This tends not
2326+ # to be the way of modern systems, but it's conceivable.)
2327+
2328+ # (Note 2: On some systems, notably Darwin, -pthread is not needed
2329+ # to get POSIX threads support; the API is always present and
2330+ # active. We could reasonably leave PTHREAD_CFLAGS empty. But
2331+ # -pthread does define _REENTRANT, and while the Darwin headers
2332+ # ignore this macro, third-party headers might not.)
2333+
2334+ # However, older versions of Clang make a point of warning the user
2335+ # that, in an invocation where only linking and no compilation is
2336+ # taking place, the -pthread option has no effect ("argument unused
2337+ # during compilation"). They expect -pthread to be passed in only
2338+ # when source code is being compiled.
2339+ #
2340+ # Problem is, this is at odds with the way Automake and most other
2341+ # C build frameworks function, which is that the same flags used in
2342+ # compilation (CFLAGS) are also used in linking. Many systems
2343+ # supported by AX_PTHREAD require exactly this for POSIX threads
2344+ # support, and in fact it is often not straightforward to specify a
2345+ # flag that is used only in the compilation phase and not in
2346+ # linking. Such a scenario is extremely rare in practice.
2347+ #
2348+ # Even though use of the -pthread flag in linking would only print
2349+ # a warning, this can be a nuisance for well-run software projects
2350+ # that build with -Werror. So if the active version of Clang has
2351+ # this misfeature, we search for an option to squash it.
2352+
2353+ AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
2354+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
2355+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
2356+ # Create an alternate version of $ac_link that compiles and
2357+ # links in two steps (.c -> .o, .o -> exe) instead of one
2358+ # (.c -> exe), because the warning occurs only in the second
2359+ # step
2360+ ax_pthread_save_ac_link="$ac_link"
2361+ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
2362+ ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
2363+ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
2364+ ax_pthread_save_CFLAGS="$CFLAGS"
2365+ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
2366+ AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
2367+ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
2368+ ac_link="$ax_pthread_save_ac_link"
2369+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
2370+ [ac_link="$ax_pthread_2step_ac_link"
2371+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
2372+ [break])
2373+ ])
2374+ done
2375+ ac_link="$ax_pthread_save_ac_link"
2376+ CFLAGS="$ax_pthread_save_CFLAGS"
2377+ AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
2378+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
2379+ ])
2380+
2381+ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
2382+ no | unknown) ;;
2383+ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
2384+ esac
2385+
2386+fi # $ax_pthread_clang = yes
2387+
2388+
2389+
2390 # Various other checks:
2391-if test "x$ax_pthread_ok" = xyes; then
2392- save_LIBS="$LIBS"
2393- LIBS="$PTHREAD_LIBS $LIBS"
2394- save_CFLAGS="$CFLAGS"
2395+if test "x$ax_pthread_ok" = "xyes"; then
2396+ ax_pthread_save_CFLAGS="$CFLAGS"
2397+ ax_pthread_save_LIBS="$LIBS"
2398 CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
2399+ LIBS="$PTHREAD_LIBS $LIBS"
2400
2401 # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
2402- AC_MSG_CHECKING([for joinable pthread attribute])
2403- attr_name=unknown
2404- for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
2405- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
2406- [int attr = $attr; return attr /* ; */])],
2407- [attr_name=$attr; break],
2408- [])
2409- done
2410- AC_MSG_RESULT($attr_name)
2411- if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
2412- AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
2413- [Define to necessary symbol if this constant
2414- uses a non-standard name on your system.])
2415- fi
2416+ AC_CACHE_CHECK([for joinable pthread attribute],
2417+ [ax_cv_PTHREAD_JOINABLE_ATTR],
2418+ [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
2419+ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
2420+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
2421+ [int attr = $ax_pthread_attr; return attr /* ; */])],
2422+ [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
2423+ [])
2424+ done
2425+ ])
2426+ AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
2427+ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
2428+ test "x$ax_pthread_joinable_attr_defined" != "xyes"],
2429+ [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
2430+ [$ax_cv_PTHREAD_JOINABLE_ATTR],
2431+ [Define to necessary symbol if this constant
2432+ uses a non-standard name on your system.])
2433+ ax_pthread_joinable_attr_defined=yes
2434+ ])
2435
2436- AC_MSG_CHECKING([if more special flags are required for pthreads])
2437- flag=no
2438- case "${host_cpu}-${host_os}" in
2439- *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
2440- *-osf* | *-hpux*) flag="-D_REENTRANT";;
2441- *solaris*)
2442- if test "$GCC" = "yes"; then
2443- flag="-D_REENTRANT"
2444- else
2445- flag="-mt -D_REENTRANT"
2446- fi
2447- ;;
2448- esac
2449- AC_MSG_RESULT(${flag})
2450- if test "x$flag" != xno; then
2451- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
2452- fi
2453+ AC_CACHE_CHECK([whether more special flags are required for pthreads],
2454+ [ax_cv_PTHREAD_SPECIAL_FLAGS],
2455+ [ax_cv_PTHREAD_SPECIAL_FLAGS=no
2456+ case $host_os in
2457+ solaris*)
2458+ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
2459+ ;;
2460+ esac
2461+ ])
2462+ AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
2463+ test "x$ax_pthread_special_flags_added" != "xyes"],
2464+ [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
2465+ ax_pthread_special_flags_added=yes])
2466
2467 AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
2468- ax_cv_PTHREAD_PRIO_INHERIT, [
2469- AC_LINK_IFELSE([
2470- AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
2471- [ax_cv_PTHREAD_PRIO_INHERIT=yes],
2472- [ax_cv_PTHREAD_PRIO_INHERIT=no])
2473+ [ax_cv_PTHREAD_PRIO_INHERIT],
2474+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
2475+ [[int i = PTHREAD_PRIO_INHERIT;
2476+ return i;]])],
2477+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
2478+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
2479 ])
2480- AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
2481- AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
2482+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
2483+ test "x$ax_pthread_prio_inherit_defined" != "xyes"],
2484+ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
2485+ ax_pthread_prio_inherit_defined=yes
2486+ ])
2487
2488- LIBS="$save_LIBS"
2489- CFLAGS="$save_CFLAGS"
2490+ CFLAGS="$ax_pthread_save_CFLAGS"
2491+ LIBS="$ax_pthread_save_LIBS"
2492
2493- # More AIX lossage: must compile with xlc_r or cc_r
2494- if test x"$GCC" != xyes; then
2495- AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
2496- else
2497- PTHREAD_CC=$CC
2498+ # More AIX lossage: compile with *_r variant
2499+ if test "x$GCC" != "xyes"; then
2500+ case $host_os in
2501+ aix*)
2502+ AS_CASE(["x/$CC"],
2503+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
2504+ [#handle absolute path differently from PATH based program lookup
2505+ AS_CASE(["x$CC"],
2506+ [x/*],
2507+ [
2508+ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
2509+ AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
2510+ ],
2511+ [
2512+ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
2513+ AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
2514+ ]
2515+ )
2516+ ])
2517+ ;;
2518+ esac
2519 fi
2520-else
2521- PTHREAD_CC="$CC"
2522 fi
2523
2524-AC_SUBST(PTHREAD_LIBS)
2525-AC_SUBST(PTHREAD_CFLAGS)
2526-AC_SUBST(PTHREAD_CC)
2527+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
2528+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
2529+
2530+AC_SUBST([PTHREAD_LIBS])
2531+AC_SUBST([PTHREAD_CFLAGS])
2532+AC_SUBST([PTHREAD_CC])
2533+AC_SUBST([PTHREAD_CXX])
2534
2535 # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
2536-if test x"$ax_pthread_ok" = xyes; then
2537- ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
2538+if test "x$ax_pthread_ok" = "xyes"; then
2539+ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
2540 :
2541 else
2542 ax_pthread_ok=no
2543diff --git a/scripts/checks.m4 b/scripts/checks.m4
2544index 915a5011..b9095cee 100644
2545--- a/scripts/checks.m4
2546+++ b/scripts/checks.m4
2547@@ -21,7 +21,7 @@ AC_DEFUN([TORRENT_CHECK_XFS], [
2548
2549 AC_DEFUN([TORRENT_WITHOUT_XFS], [
2550 AC_ARG_WITH(xfs,
2551- AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]),
2552+ AS_HELP_STRING([--without-xfs],[do not check for XFS filesystem support]),
2553 [
2554 if test "$withval" = "yes"; then
2555 TORRENT_CHECK_XFS
2556@@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [
2557
2558 AC_DEFUN([TORRENT_WITH_XFS], [
2559 AC_ARG_WITH(xfs,
2560- AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]),
2561+ AS_HELP_STRING([--with-xfs],[check for XFS filesystem support]),
2562 [
2563 if test "$withval" = "yes"; then
2564 TORRENT_CHECK_XFS
2565@@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [
2566
2567 AC_DEFUN([TORRENT_WITHOUT_EPOLL], [
2568 AC_ARG_WITH(epoll,
2569- AC_HELP_STRING([--without-epoll], [do not check for epoll support]),
2570+ AS_HELP_STRING([--without-epoll],[do not check for epoll support]),
2571 [
2572 if test "$withval" = "yes"; then
2573 TORRENT_CHECK_EPOLL
2574@@ -134,7 +134,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
2575
2576 AC_DEFUN([TORRENT_WITH_KQUEUE], [
2577 AC_ARG_WITH(kqueue,
2578- AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]),
2579+ AS_HELP_STRING([--with-kqueue],[enable kqueue [[default=no]]]),
2580 [
2581 if test "$withval" = "yes"; then
2582 TORRENT_CHECK_KQUEUE
2583@@ -145,7 +145,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
2584
2585 AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
2586 AC_ARG_WITH(kqueue,
2587- AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]),
2588+ AS_HELP_STRING([--without-kqueue],[do not check for kqueue support]),
2589 [
2590 if test "$withval" = "yes"; then
2591 TORRENT_CHECK_KQUEUE
2592@@ -158,7 +158,7 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
2593
2594 AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
2595 AC_ARG_WITH(variable-fdset,
2596- AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]),
2597+ AS_HELP_STRING([--without-variable-fdset],[do not use non-portable variable sized fd_set's]),
2598 [
2599 if test "$withval" = "yes"; then
2600 AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size)
2601@@ -172,14 +172,13 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
2602 AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
2603 AC_MSG_CHECKING(for fallocate)
2604
2605- AC_TRY_LINK([#define _GNU_SOURCE
2606+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE
2607 #include <fcntl.h>
2608- ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
2609- ],
2610- [
2611+ ]], [[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
2612+ ]])],[
2613 AC_DEFINE(HAVE_FALLOCATE, 1, Linux's fallocate supported.)
2614 AC_MSG_RESULT(yes)
2615- ], [
2616+ ],[
2617 AC_MSG_RESULT(no)
2618 ])
2619 ])
2620@@ -188,13 +187,12 @@ AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
2621 AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
2622 AC_MSG_CHECKING(for posix_fallocate)
2623
2624- AC_TRY_LINK([#include <fcntl.h>
2625- ],[ posix_fallocate(0, 0, 0);
2626- ],
2627- [
2628+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fcntl.h>
2629+ ]], [[ posix_fallocate(0, 0, 0);
2630+ ]])],[
2631 AC_DEFINE(USE_POSIX_FALLOCATE, 1, posix_fallocate supported.)
2632 AC_MSG_RESULT(yes)
2633- ], [
2634+ ],[
2635 AC_MSG_RESULT(no)
2636 ])
2637 ])
2638@@ -202,7 +200,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
2639
2640 AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [
2641 AC_ARG_WITH(posix-fallocate,
2642- AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]),
2643+ AS_HELP_STRING([--with-posix-fallocate],[check for and use posix_fallocate to allocate files]),
2644 [
2645 if test "$withval" = "yes"; then
2646 TORRENT_CHECK_POSIX_FALLOCATE
2647@@ -215,8 +213,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
2648
2649 AC_MSG_CHECKING(for statvfs)
2650
2651- AC_TRY_LINK(
2652- [
2653+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
2654 #if HAVE_SYS_VFS_H
2655 #include <sys/vfs.h>
2656 #endif
2657@@ -226,12 +223,11 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
2658 #if HAVE_SYS_STATFS_H
2659 #include <sys/statfs.h>
2660 #endif
2661- ],[
2662+ ]], [[
2663 struct statvfs s; fsblkcnt_t c;
2664 statvfs("", &s);
2665 fstatvfs(0, &s);
2666- ],
2667- [
2668+ ]])],[
2669 AC_DEFINE(FS_STAT_FD, [fstatvfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
2670 AC_DEFINE(FS_STAT_FN, [statvfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
2671 AC_DEFINE(FS_STAT_STRUCT, [struct statvfs], Type of second argument to statfs function)
2672@@ -240,8 +236,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
2673 AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_frsize)], Determine the block size)
2674 AC_MSG_RESULT(ok)
2675 have_stat_vfs=yes
2676- ],
2677- [
2678+ ],[
2679 AC_MSG_RESULT(no)
2680 have_stat_vfs=no
2681 ])
2682@@ -252,8 +247,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
2683
2684 AC_MSG_CHECKING(for statfs)
2685
2686- AC_TRY_LINK(
2687- [
2688+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
2689 #if HAVE_SYS_STATFS_H
2690 #include <sys/statfs.h>
2691 #endif
2692@@ -263,12 +257,11 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
2693 #if HAVE_SYS_MOUNT_H
2694 #include <sys/mount.h>
2695 #endif
2696- ],[
2697+ ]], [[
2698 struct statfs s;
2699 statfs("", &s);
2700 fstatfs(0, &s);
2701- ],
2702- [
2703+ ]])],[
2704 AC_DEFINE(FS_STAT_FD, [fstatfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
2705 AC_DEFINE(FS_STAT_FN, [statfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
2706 AC_DEFINE(FS_STAT_STRUCT, [struct statfs], Type of second argument to statfs function)
2707@@ -277,8 +270,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
2708 AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_bsize)], Determine the block size)
2709 AC_MSG_RESULT(ok)
2710 have_stat_vfs=yes
2711- ],
2712- [
2713+ ],[
2714 AC_MSG_RESULT(no)
2715 have_stat_vfs=no
2716 ])
2717@@ -296,7 +288,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [
2718
2719 AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
2720 AC_ARG_WITH(statvfs,
2721- AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]),
2722+ AS_HELP_STRING([--without-statvfs],[don't try to use statvfs to find free diskspace]),
2723 [
2724 if test "$withval" = "yes"; then
2725 TORRENT_CHECK_STATVFS
2726@@ -311,7 +303,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
2727
2728 AC_DEFUN([TORRENT_WITHOUT_STATFS], [
2729 AC_ARG_WITH(statfs,
2730- AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]),
2731+ AS_HELP_STRING([--without-statfs],[don't try to use statfs to find free diskspace]),
2732 [
2733 if test "$have_stat_vfs" = "no"; then
2734 if test "$withval" = "yes"; then
2735@@ -333,7 +325,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [
2736
2737 AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
2738 AC_ARG_WITH(address-space,
2739- AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]),
2740+ AS_HELP_STRING([--with-address-space=MB],[change the default address space size [[default=1024mb]]]),
2741 [
2742 if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then
2743 AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval])
2744@@ -354,7 +346,7 @@ AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
2745
2746 AC_DEFUN([TORRENT_WITH_FASTCGI], [
2747 AC_ARG_WITH(fastcgi,
2748- AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]),
2749+ AS_HELP_STRING([--with-fastcgi=PATH],[enable FastCGI RPC support (DO NOT USE)]),
2750 [
2751 AC_MSG_CHECKING([for FastCGI (DO NOT USE)])
2752
2753@@ -365,13 +357,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [
2754 CXXFLAGS="$CXXFLAGS"
2755 LIBS="$LIBS -lfcgi"
2756
2757- AC_TRY_LINK(
2758- [ #include <fcgiapp.h>
2759- ],[ FCGX_Init(); ],
2760- [
2761+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <fcgiapp.h>
2762+ ]], [[ FCGX_Init(); ]])],[
2763 AC_MSG_RESULT(ok)
2764- ],
2765- [
2766+ ],[
2767 AC_MSG_RESULT(not found)
2768 AC_MSG_ERROR(Could not compile FastCGI test.)
2769 ])
2770@@ -382,13 +371,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [
2771 CXXFLAGS="$CXXFLAGS -I$withval/include"
2772 LIBS="$LIBS -lfcgi -L$withval/lib"
2773
2774- AC_TRY_LINK(
2775- [ #include <fcgiapp.h>
2776- ],[ FCGX_Init(); ],
2777- [
2778+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <fcgiapp.h>
2779+ ]], [[ FCGX_Init(); ]])],[
2780 AC_MSG_RESULT(ok)
2781- ],
2782- [
2783+ ],[
2784 AC_MSG_RESULT(not found)
2785 AC_MSG_ERROR(Could not compile FastCGI test.)
2786 ])
2787@@ -403,7 +389,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
2788 AC_MSG_CHECKING(for XMLRPC-C)
2789
2790 AC_ARG_WITH(xmlrpc-c,
2791- AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]),
2792+ AS_HELP_STRING([--with-xmlrpc-c=PATH],[enable XMLRPC-C support]),
2793 [
2794 if test "$withval" = "no"; then
2795 AC_MSG_RESULT(no)
2796@@ -419,12 +405,10 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
2797 CXXFLAGS="$CXXFLAGS `$xmlrpc_cc_prg --cflags server-util`"
2798 LIBS="$LIBS `$xmlrpc_cc_prg server-util --libs`"
2799
2800- AC_TRY_LINK(
2801- [ #include <xmlrpc-c/server.h>
2802- ],[ xmlrpc_registry_new(NULL); ],
2803- [
2804+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <xmlrpc-c/server.h>
2805+ ]], [[ xmlrpc_registry_new(NULL); ]])],[
2806 AC_MSG_RESULT(ok)
2807- ], [
2808+ ],[
2809 AC_MSG_RESULT(failed)
2810 AC_MSG_ERROR(Could not compile XMLRPC-C test.)
2811 ])
2812@@ -466,23 +450,23 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
2813
2814 AC_MSG_CHECKING(for pthread_setname_np type)
2815
2816- AC_TRY_LINK([
2817+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
2818 #include <pthread.h>
2819 #include <sys/types.h>
2820- ],[
2821+ ]], [[
2822 pthread_t t;
2823 pthread_setname_np(t, "foo");
2824- ],[
2825+ ]])],[
2826 AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.)
2827 AC_MSG_RESULT(generic)
2828 ],[
2829- AC_TRY_LINK([
2830+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
2831 #include <pthread.h>
2832 #include <sys/types.h>
2833- ],[
2834+ ]],[[
2835 pthread_t t;
2836 pthread_setname_np("foo");
2837- ],[
2838+ ]])],[
2839 AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.)
2840 AC_MSG_RESULT(darwin)
2841 ],[
2842@@ -495,7 +479,7 @@ AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [
2843 AC_MSG_CHECKING([for pthread_setname_no])
2844
2845 AC_ARG_ENABLE(pthread-setname-np,
2846- AC_HELP_STRING([--disable-pthread-setname-np], [disable pthread_setname_np]),
2847+ AS_HELP_STRING([--disable-pthread-setname-np],[disable pthread_setname_np]),
2848 [
2849 if test "$enableval" = "no"; then
2850 AC_MSG_RESULT(disabled)
2851diff --git a/scripts/common.m4 b/scripts/common.m4
2852index 55e8d66e..2f54402e 100644
2853--- a/scripts/common.m4
2854+++ b/scripts/common.m4
2855@@ -1,6 +1,7 @@
2856 AC_DEFUN([TORRENT_WITH_SYSROOT], [
2857 AC_ARG_WITH(sysroot,
2858- AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]),
2859+ AS_HELP_STRING([--with-sysroot=PATH],
2860+ [compile and link with a specific sysroot]),
2861 [
2862 AC_MSG_CHECKING(for sysroot)
2863
2864@@ -22,7 +23,8 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [
2865
2866 AC_DEFUN([TORRENT_ENABLE_ARCH], [
2867 AC_ARG_ENABLE(arch,
2868- AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]),
2869+ AS_HELP_STRING([--enable-arch=ARCH],
2870+ [comma seprated list of architectures to compile for]),
2871 [
2872 AC_MSG_CHECKING(for target architectures)
2873
2874@@ -82,7 +84,8 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [
2875
2876 AC_DEFUN([TORRENT_MINCORE], [
2877 AC_ARG_ENABLE(mincore,
2878- AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]),
2879+ AS_HELP_STRING([--disable-mincore],
2880+ [disable mincore check [[default=enable]]]),
2881 [
2882 if test "$enableval" = "yes"; then
2883 TORRENT_MINCORE_SIGNEDNESS()
2884@@ -174,7 +177,8 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [
2885
2886 AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
2887 AC_ARG_ENABLE(aligned,
2888- AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]),
2889+ AS_HELP_STRING([--enable-aligned],
2890+ [enable alignment safe code [[default=check]]]),
2891 [
2892 if test "$enableval" = "yes"; then
2893 AC_DEFINE(USE_ALIGNED, 1, Require byte alignment)
2894@@ -189,7 +193,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
2895 AC_MSG_CHECKING([if instrumentation should be included])
2896
2897 AC_ARG_ENABLE(instrumentation,
2898- AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]),
2899+ AS_HELP_STRING([--disable-instrumentation],
2900+ [disable instrumentation [[default=enabled]]]),
2901 [
2902 if test "$enableval" = "yes"; then
2903 AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
2904@@ -206,7 +211,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
2905
2906 AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
2907 AC_ARG_ENABLE(interrupt-socket,
2908- AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]),
2909+ AS_HELP_STRING([--enable-interrupt-socket],
2910+ [enable interrupt socket [[default=no]]]),
2911 [
2912 if test "$enableval" = "yes"; then
2913 AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill)
2914@@ -214,3 +220,14 @@ AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
2915 ]
2916 )
2917 ])
2918+
2919+AC_DEFUN([TORRENT_DISABLE_IPV6], [
2920+ AC_ARG_ENABLE(ipv6,
2921+ AS_HELP_STRING([--enable-ipv6],
2922+ [enable ipv6 [[default=no]]]),
2923+ [
2924+ if test "$enableval" = "yes"; then
2925+ AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff)
2926+ fi
2927+ ])
2928+])
2929diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4
2930index 9a361bed..bc1572a3 100644
2931--- a/scripts/rak_compiler.m4
2932+++ b/scripts/rak_compiler.m4
2933@@ -26,7 +26,7 @@ AC_DEFUN([RAK_CHECK_CXXFLAGS], [
2934
2935 AC_DEFUN([RAK_ENABLE_DEBUG], [
2936 AC_ARG_ENABLE(debug,
2937- AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
2938+ AS_HELP_STRING([--enable-debug],[enable debug information [[default=yes]]]),
2939 [
2940 if test "$enableval" = "yes"; then
2941 CXXFLAGS="$CXXFLAGS -g -DDEBUG"
2942@@ -41,7 +41,7 @@ AC_DEFUN([RAK_ENABLE_DEBUG], [
2943
2944 AC_DEFUN([RAK_ENABLE_WERROR], [
2945 AC_ARG_ENABLE(werror,
2946- AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flags [[default -Wall only]]]),
2947+ AS_HELP_STRING([--enable-werror],[enable the -Werror and -Wall flags [[default -Wall only]]]),
2948 [
2949 if test "$enableval" = "yes"; then
2950 CXXFLAGS="$CXXFLAGS -Werror -Wall"
2951@@ -54,7 +54,7 @@ AC_DEFUN([RAK_ENABLE_WERROR], [
2952
2953 AC_DEFUN([RAK_ENABLE_EXTRA_DEBUG], [
2954 AC_ARG_ENABLE(extra-debug,
2955- AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]),
2956+ AS_HELP_STRING([--enable-extra-debug],[enable extra debugging checks [[default=no]]]),
2957 [
2958 if test "$enableval" = "yes"; then
2959 AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.)
2960diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4
2961deleted file mode 100644
2962index 0db61b83..00000000
2963--- a/scripts/rak_cxx.m4
2964+++ /dev/null
2965@@ -1,14 +0,0 @@
2966-AC_DEFUN([RAK_CHECK_CXX11], [
2967- AC_ARG_ENABLE([c++0x],
2968- AC_HELP_STRING([--enable-c++0x], [compile with C++0x (unsupported)]),
2969- [
2970- if test "$enableval" = "yes"; then
2971- AX_CXX_COMPILE_STDCXX_0X
2972- else
2973- AX_CXX_COMPILE_STDCXX_11(noext)
2974- fi
2975- ],[
2976- AX_CXX_COMPILE_STDCXX_11(noext)
2977- ]
2978- )
2979-])
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch
new file mode 100644
index 0000000000..b9378f503a
--- /dev/null
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch
@@ -0,0 +1,29 @@
1From eca577e2a29d64251b5df1c69be53c5b1ffe6bde Mon Sep 17 00:00:00 2001
2From: Jari Sundell <sundell.software@gmail.com>
3Date: Thu, 8 Sep 2022 05:08:44 +0900
4Subject: [PATCH] Create FUNDING.yml
5
6---
7 .github/FUNDING.yml | 13 +++++++++++++
8 1 file changed, 13 insertions(+)
9 create mode 100644 .github/FUNDING.yml
10
11diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
12new file mode 100644
13index 00000000..ad5998e8
14--- /dev/null
15+++ b/.github/FUNDING.yml
16@@ -0,0 +1,13 @@
17+# These are supported funding model platforms
18+
19+github: [rakshasa]
20+patreon: rtorrent
21+open_collective: # Replace with a single Open Collective username
22+ko_fi: # Replace with a single Ko-fi username
23+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
24+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
25+liberapay: # Replace with a single Liberapay username
26+issuehunt: # Replace with a single IssueHunt username
27+otechie: # Replace with a single Otechie username
28+lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
29+custom: ['https://rakshasa.github.io/rtorrent/donate.html']
diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb b/meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb
index fec05571d1..70c173be54 100644
--- a/meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb
+++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb
@@ -6,12 +6,57 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833"
6 6
7DEPENDS = "zlib libsigc++-2.0 openssl cppunit" 7DEPENDS = "zlib libsigc++-2.0 openssl cppunit"
8 8
9SRC_URI = "git://github.com/rakshasa/libtorrent;branch=master;protocol=https" 9SRC_URI = "git://github.com/rakshasa/libtorrent;branch=master;protocol=https \
10SRCREV = "e60f222241319aaae482789517ad00ae9344bd13" 10 file://0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch \
11 file://0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch \
12 file://0003-Add-space-to-fmt-str-in-log_gz_file_write.patch \
13 file://0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch \
14 file://0005-Disable-extents-test-to-pass-TravisCI-See-11.patch \
15 file://0006-Bumped-version-to-0.13.7.patch \
16 file://0007-Added-support-for-openssl-1.1.patch \
17 file://0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch \
18 file://0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch \
19 file://0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch \
20 file://0011-Strip-tags-also-when-displaying-info-on-failed-track.patch \
21 file://0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch \
22 file://0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch \
23 file://0014-If-during-socket-creation-AF_INET6-failes-initialize.patch \
24 file://0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch \
25 file://0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch \
26 file://0017-increase-piece-length-max.patch \
27 file://0018-Set-max-piece-size-512mb.patch \
28 file://0019-Fixed-compiler-warning.patch \
29 file://0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch \
30 file://0021-Fixed-diffie-hellman-implementation.patch \
31 file://0022-Increased-max-timeout-for-tracker-requests.patch \
32 file://0023-Close-log-files-when-reusing-a-name.patch \
33 file://0024-Bumped-to-version-0.13.8.patch \
34 file://0025-Allow-logs-to-be-appended-rather-than-overwritten.patch \
35 file://0026-Removed-log-append-function.-Added-append-parameter-.patch \
36 file://0027-Backport-changes-from-feature-bind.-200.patch \
37 file://0028-libtorrent.pc.in-add-Libs.Private-202.patch \
38 file://0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch \
39 file://0030-Fix-compiler-warnings.-204.patch \
40 file://0031-Fix-log-format-so-GCC-can-check-it.-205.patch \
41 file://0032-Consolidate-make-script-to-optimize-build.-206.patch \
42 file://0033-Refactor-make-process.-207.patch \
43 file://0034-Changes-automake-required-files.patch \
44 file://0035-Replaced-custom-execinfo-autoconf-test.patch \
45 file://0036-Added-option-to-disable-pthread_setname_np.patch \
46 file://0037-Improved-backtrace-error-checking.patch \
47 file://0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch \
48 file://0039-Added-disable-execinfo-option-to-configure.patch \
49 file://0040-Detect-ip-address.patch \
50 file://0041-Added-ipv6-options.patch \
51 file://0042-Removed-obsolete-files.patch \
52 file://0043-Updated-and-cleaned-up-automake.-224.patch \
53 file://0044-Create-FUNDING.yml.patch \
54 "
55SRCREV = "c167c5a9e0bcf0df23ae5efd91396aae0e37eb87"
11 56
12CVE_STATUS[CVE-2009-1760] = "backported-patch: patched in our product" 57CVE_STATUS[CVE-2009-1760] = "backported-patch: patched in our product"
13 58
14PV = "0.13.8+git${SRCPV}" 59PV = "1"
15 60
16S = "${WORKDIR}/git" 61S = "${WORKDIR}/git"
17 62