From patchwork Fri Nov 3 19:52:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: auh@yoctoproject.org X-Patchwork-Id: 33952 Return-Path: Received: from aws-us-west-2-korg-lkml-1.web.codeaurora.org (localhost.localdomain [127.0.0.1]) by smtp.lore.kernel.org (Postfix) with ESMTP id E8566C4167D for ; Fri, 3 Nov 2023 19:52:55 +0000 (UTC) Received: from a27-191.smtp-out.us-west-2.amazonses.com (a27-191.smtp-out.us-west-2.amazonses.com [54.240.27.191]) by mx.groups.io with SMTP id smtpd.web10.63863.1699041165611404386 for ; Fri, 03 Nov 2023 12:52:54 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@yoctoproject.org header.s=lvjh2tk576v2ro5mi6k4dt3mc6wpqbky header.b=HH15uAI3; dkim=pass header.i=@amazonses.com header.s=hsbnp7p3ensaochzwyq5wwmceodymuwv header.b=ZF0RYP5A; spf=pass (domain: us-west-2.amazonses.com, ip: 54.240.27.191, mailfrom: 0101018b96bedeff-ef74b4dd-cfbe-4927-ab9a-b72a3ae10603-000000@us-west-2.amazonses.com) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=lvjh2tk576v2ro5mi6k4dt3mc6wpqbky; d=yoctoproject.org; t=1699041173; h=Content-Type:MIME-Version:From:To:Cc:Subject:Message-Id:Date; bh=nrtUb9gGfoqGzLVW0FfxjbGYyanzLKWkDioW3C3T33Q=; b=HH15uAI3EwfhhLJZHzeosAsb8p2rG5y4aU12EadIem2+zuBbwCxk4Dt0MO5hAyvI qBWgRwWOpNCpPERVGDSmHKgbZKw4to38WYzzHYEZIgx6vhix8/QQKwxmlVcRSCx5a4r PfNJ7of+30jvtBB8pGdrBnKOBBeiZhQ3+pyMyGG8= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/simple; s=hsbnp7p3ensaochzwyq5wwmceodymuwv; d=amazonses.com; t=1699041173; h=Content-Type:MIME-Version:From:To:Cc:Subject:Message-Id:Date:Feedback-ID; bh=nrtUb9gGfoqGzLVW0FfxjbGYyanzLKWkDioW3C3T33Q=; b=ZF0RYP5AnzIgK4Rkrb4s2ekUWMbnLNvCfKMdvAGNt+fg4RrgRjHkhfGLODJPcE+r jOO/LcV8znI02wAJSl4j73qe4Hlf7hHp2vQrAQjAQPhxb5NCdOt7tLpcCvhF2WvSk8U 7NxKNCFkkvwK0BnbgZ5yeH0kAglqSzwftmHG8/vM= MIME-Version: 1.0 From: auh@yoctoproject.org To: Forced@yoctoproject.org, maintainer@yoctoproject.org, for@yoctoproject.org, AUH@yoctoproject.org Cc: openembedded-devel@lists.openembedded.org Subject: [AUH] libtorrent: upgrading to 1 SUCCEEDED Message-ID: <0101018b96bedeff-ef74b4dd-cfbe-4927-ab9a-b72a3ae10603-000000@us-west-2.amazonses.com> Date: Fri, 3 Nov 2023 19:52:53 +0000 Feedback-ID: 1.us-west-2.9np3MYPs3fEaOBysGKSlUD4KtcmPijcmS9Az2Hwf7iQ=:AmazonSES X-SES-Outgoing: 2023.11.03-54.240.27.191 List-Id: X-Webhook-Received: from li982-79.members.linode.com [45.33.32.79] by aws-us-west-2-korg-lkml-1.web.codeaurora.org with HTTPS for ; Fri, 03 Nov 2023 19:52:55 -0000 X-Groupsio-URL: https://lists.openembedded.org/g/openembedded-devel/message/106013 Hello, this email is a notification from the Auto Upgrade Helper that the automatic attempt to upgrade the recipe *libtorrent* to *1* has Succeeded. Next steps: - apply the patch: git am 0001-libtorrent-upgrade-0.13.8-1.patch - check the changes to upstream patches and summarize them in the commit message, - compile an image that contains the package - perform some basic sanity tests - amend the patch and sign it off: git commit -s --reset-author --amend - send it to the appropriate mailing list Alternatively, if you believe the recipe should not be upgraded at this time, you can fill RECIPE_NO_UPDATE_REASON in respective recipe file so that automatic upgrades would no longer be attempted. Please review the attached files for further information and build/update failures. Any problem please file a bug at https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Automated%20Update%20Handler Regards, The Upgrade Helper -- >8 -- From 83a38bc5603090648c65b7bd15a471401a083a6e Mon Sep 17 00:00:00 2001 From: Upgrade Helper Date: Fri, 3 Nov 2023 15:07:47 +0000 Subject: [PATCH] libtorrent: upgrade 0.13.8 -> 1 --- ...issue-with-gcc-v6.x-and-empty-CXXFLA.patch | 44 + ...c-v6.x-fix-for-empty-CXXFLAGS-See-10.patch | 56 + ...pace-to-fmt-str-in-log_gz_file_write.patch | 27 + ...ncement-11IPv4-filter-enhancement-Cl.patch | 379 + ...extents-test-to-pass-TravisCI-See-11.patch | 47 + .../0006-Bumped-version-to-0.13.7.patch | 30 + .../0007-Added-support-for-openssl-1.1.patch | 105 + ...nstead-of-AC_RUN-to-check-for-execin.patch | 24 + ...-to-prevent-unnecessary-kqueue-check.patch | 46 + ...failed-tracker-bencode-parsing-See-9.patch | 58 + ...when-displaying-info-on-failed-track.patch | 60 + ...tch-to-C-11-MRT-RNG-for-random-bytes.patch | 45 + ...m_ipv6_socket-attribute-which-led-to.patch | 45 + ...-creation-AF_INET6-failes-initialize.patch | 27 + ...hub.com-rakshasa-rtorrent-issues-731.patch | 29 + ...ottle.min_peers-settings-in-rtorrent.patch | 40 + .../0017-increase-piece-length-max.patch | 22 + .../0018-Set-max-piece-size-512mb.patch | 22 + .../0019-Fixed-compiler-warning.patch | 22 + ..._GNU_SOURCE-to-fallocate-test.-neheb.patch | 74 + ...-Fixed-diffie-hellman-implementation.patch | 293 + ...sed-max-timeout-for-tracker-requests.patch | 64 + ...-Close-log-files-when-reusing-a-name.patch | 123 + .../0024-Bumped-to-version-0.13.8.patch | 30 + ...-be-appended-rather-than-overwritten.patch | 109 + ...nd-function.-Added-append-parameter-.patch | 101 + ...kport-changes-from-feature-bind.-200.patch | 7365 +++++++++++++++++ ...ibtorrent.pc.in-add-Libs.Private-202.patch | 26 + ...fy-missing-quickly-renamed-files-203.patch | 27 + .../0030-Fix-compiler-warnings.-204.patch | 470 ++ ...-log-format-so-GCC-can-check-it.-205.patch | 33 + ...e-make-script-to-optimize-build.-206.patch | 843 ++ .../0033-Refactor-make-process.-207.patch | 2710 ++++++ ...0034-Changes-automake-required-files.patch | 22 + ...placed-custom-execinfo-autoconf-test.patch | 48 + ...option-to-disable-pthread_setname_np.patch | 135 + ...37-Improved-backtrace-error-checking.patch | 594 ++ ...-multiple-connections-from-NAT-not-w.patch | 199 + ...disable-execinfo-option-to-configure.patch | 32 + .../libtorrent/0040-Detect-ip-address.patch | 457 + .../libtorrent/0041-Added-ipv6-options.patch | 85 + .../0042-Removed-obsolete-files.patch | 444 + ...Updated-and-cleaned-up-automake.-224.patch | 2979 +++++++ .../libtorrent/0044-Create-FUNDING.yml.patch | 29 + .../libtorrent/libtorrent_git.bb | 51 +- 45 files changed, 18468 insertions(+), 3 deletions(-) create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0003-Add-space-to-fmt-str-in-log_gz_file_write.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch create mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch 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 000000000..bc4bade51 --- /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 @@ +From c2b119de0e66fb047bb20e445ac8e25824448858 Mon Sep 17 00:00:00 2001 +From: chros +Date: Sun, 30 Jul 2017 20:34:47 +0100 +Subject: [PATCH] Fix compilation issue with gcc v6.x and empty CXXFLAGS (See + #10) + +--- + configure.ac | 1 + + scripts/rak_compiler.m4 | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + +diff --git a/configure.ac b/configure.ac +index 65e34872..2f29e3f9 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -28,6 +28,7 @@ AC_C_BIGENDIAN( + AC_MSG_ERROR([Could not determine endianness]) + ) + ++RAK_CHECK_CXXFLAGS + RAK_ENABLE_DEBUG + RAK_ENABLE_EXTRA_DEBUG + RAK_ENABLE_WERROR +diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4 +index 39bd19a7..87871abf 100644 +--- a/scripts/rak_compiler.m4 ++++ b/scripts/rak_compiler.m4 +@@ -1,3 +1,16 @@ ++AC_DEFUN([RAK_CHECK_CXXFLAGS], [ ++ ++ AC_MSG_CHECKING([for user-defined CXXFLAGS]) ++ ++ if test -n "$CXXFLAGS"; then ++ AC_MSG_RESULT([user-defined "$CXXFLAGS"]) ++ else ++ CXXFLAGS="-O2" ++ AC_MSG_RESULT([default "$CXXFLAGS"]) ++ fi ++]) ++ ++ + AC_DEFUN([RAK_ENABLE_DEBUG], [ + AC_ARG_ENABLE(debug, + AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]), 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 000000000..532b65a7c --- /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 @@ +From 8229218dff1105e9fb2bb2c7510910a0db98f3ef Mon Sep 17 00:00:00 2001 +From: chros +Date: Wed, 2 Aug 2017 12:48:27 +0100 +Subject: [PATCH] Modfiy gcc v6.x fix for empty CXXFLAGS (See #10) + +--- + configure.ac | 1 + + scripts/rak_compiler.m4 | 21 +++++++++++++++++---- + 2 files changed, 18 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 2f29e3f9..a6df6b80 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -28,6 +28,7 @@ AC_C_BIGENDIAN( + AC_MSG_ERROR([Could not determine endianness]) + ) + ++RAK_CHECK_CFLAGS + RAK_CHECK_CXXFLAGS + RAK_ENABLE_DEBUG + RAK_ENABLE_EXTRA_DEBUG +diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4 +index 87871abf..9a361bed 100644 +--- a/scripts/rak_compiler.m4 ++++ b/scripts/rak_compiler.m4 +@@ -1,12 +1,25 @@ ++AC_DEFUN([RAK_CHECK_CFLAGS], [ ++ ++ AC_MSG_CHECKING([for user-defined CFLAGS]) ++ ++ if test "$CFLAGS" = ""; then ++ unset CFLAGS ++ AC_MSG_RESULT([undefined]) ++ else ++ AC_MSG_RESULT([user-defined "$CFLAGS"]) ++ fi ++]) ++ ++ + AC_DEFUN([RAK_CHECK_CXXFLAGS], [ + + AC_MSG_CHECKING([for user-defined CXXFLAGS]) + +- if test -n "$CXXFLAGS"; then +- AC_MSG_RESULT([user-defined "$CXXFLAGS"]) ++ if test "$CXXFLAGS" = ""; then ++ unset CXXFLAGS ++ AC_MSG_RESULT([undefined]) + else +- CXXFLAGS="-O2" +- AC_MSG_RESULT([default "$CXXFLAGS"]) ++ AC_MSG_RESULT([user-defined "$CXXFLAGS"]) + fi + ]) + 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 000000000..810b4d4ca --- /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 @@ +From 48635a0fdb06b8572809dc54c630109db1e6e85c Mon Sep 17 00:00:00 2001 +From: Matt Traudt +Date: Mon, 20 Nov 2017 15:22:51 -0500 +Subject: [PATCH] Add space to fmt str in log_gz_file_write + +Without this space, the log level identifier ('D', 'I', etc.) +would be right next to actual content. + +Before: Depoll->pcb(17): Open event. +After: D epoll->pcb(17): Open event. +--- + src/torrent/utils/log.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc +index 646d36e3..58b563a6 100644 +--- a/src/torrent/utils/log.cc ++++ b/src/torrent/utils/log.cc +@@ -381,7 +381,7 @@ log_gz_file_write(std::shared_ptr& outfile, const char* data, siz + + // Normal groups are nul-terminated strings. + if (group >= 0) { +- const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c"); ++ const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c "); + + int buffer_length = snprintf(buffer, 64, fmt, + cachedTime.seconds(), 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 000000000..c7a01409d --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch @@ -0,0 +1,379 @@ +From facd1b78071e315a2e5ee4992d3545dae4290e07 Mon Sep 17 00:00:00 2001 +From: chros +Date: Sun, 10 Dec 2017 18:51:32 +0000 +Subject: [PATCH] IPv4 filter enhancement #11IPv4 filter enhancement (Closes + #11) + +--- + src/torrent/peer/peer_list.cc | 23 ++- + src/torrent/peer/peer_list.h | 2 +- + src/torrent/utils/extents.h | 267 ++++++++++++++-------------------- + 3 files changed, 134 insertions(+), 158 deletions(-) + +diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc +index 23ca651a..aa60939a 100644 +--- a/src/torrent/peer/peer_list.cc ++++ b/src/torrent/peer/peer_list.cc +@@ -146,7 +146,11 @@ PeerList::insert_address(const sockaddr* sa, int flags) { + + PeerInfo* peerInfo = new PeerInfo(sa); + peerInfo->set_listen_port(address->port()); +- peerInfo->set_flags(m_ipv4_table.at(address->sa_inet()->address_h()) & PeerInfo::mask_ip_table); ++ uint32_t host_byte_order_ipv4_addr = address->sa_inet()->address_h(); ++ ++ // IPv4 addresses stored in host byte order in ipv4_table so they are comparable. ntohl has been called ++ if(m_ipv4_table.defined(host_byte_order_ipv4_addr)) ++ peerInfo->set_flags(m_ipv4_table.at(host_byte_order_ipv4_addr) & PeerInfo::mask_ip_table); + + manager->client_list()->retrieve_unknown(&peerInfo->mutable_client_info()); + +@@ -264,12 +268,25 @@ PeerList::connected(const sockaddr* sa, int flags) { + !socket_address_key::is_comparable_sockaddr(sa)) + return NULL; + +- int filter_value = m_ipv4_table.at(address->sa_inet()->address_h()); ++ uint32_t host_byte_order_ipv4_addr = address->sa_inet()->address_h(); ++ int filter_value = 0; ++ ++ // IPv4 addresses stored in host byte order in ipv4_table so they are comparable. ntohl has been called ++ if(m_ipv4_table.defined(host_byte_order_ipv4_addr)) ++ filter_value = m_ipv4_table.at(host_byte_order_ipv4_addr); + + // We should also remove any PeerInfo objects already for this + // address. +- if ((filter_value & PeerInfo::flag_unwanted)) ++ if ((filter_value & PeerInfo::flag_unwanted)) { ++ char ipv4_str[INET_ADDRSTRLEN]; ++ uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr); ++ ++ inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN); ++ ++ lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str); ++ + return NULL; ++ } + + PeerInfo* peerInfo; + range_type range = base_type::equal_range(sock_key); +diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h +index a3b409cb..4c2f707d 100644 +--- a/src/torrent/peer/peer_list.h ++++ b/src/torrent/peer/peer_list.h +@@ -46,7 +46,7 @@ namespace torrent { + + class DownloadInfo; + +-typedef extents ipv4_table; ++typedef extents ipv4_table; + + class LIBTORRENT_EXPORT PeerList : private std::multimap { + public: +diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h +index 8ec1e600..c2b887b1 100644 +--- a/src/torrent/utils/extents.h ++++ b/src/torrent/utils/extents.h +@@ -37,191 +37,150 @@ + #ifndef LIBTORRENT_UTILS_EXTENTS_H + #define LIBTORRENT_UTILS_EXTENTS_H + +-#include lt_tr1_array + +-#include ++#include ++#include + + namespace torrent { + +-template +-struct extents_base { +- typedef Key key_type; +- typedef std::pair range_type; +- typedef std::pair mapped_type; +- typedef Tp mapped_value_type; +- +- typedef std::array table_type; +- +- extents_base(key_type pos, unsigned int mb, mapped_value_type val); +- extents_base(extents_base* parent, typename table_type::const_iterator itr); +- ~extents_base(); +- +- bool is_divisible(key_type key) const { return key % mask_bits == 0; } +- bool is_leaf_branch() const { return mask_bits == 0; } +- bool is_equal_range(key_type first, key_type last, const mapped_value_type& val) const; +- +- unsigned int sizeof_data() const; +- +- typename table_type::iterator partition_at(key_type key) { return table.begin() + ((key >> mask_bits) & (TableSize - 1)); } +- typename table_type::const_iterator partition_at(key_type key) const { return table.begin() + ((key >> mask_bits) & (TableSize - 1)); } +- +- unsigned int mask_distance(unsigned int mb) { return (~(~key_type() << mb) >> mask_bits); } +- +- key_type partition_pos(typename table_type::const_iterator part) const { return position + (std::distance(table.begin(), part) << mask_bits); } +- +- void insert(key_type pos, unsigned int mb, const mapped_value_type& val); +- +- const mapped_value_type& at(key_type key) const; +- +- unsigned int mask_bits; +- key_type position; +- table_type table; +-}; +- +-template +-class extents : private extents_base { ++template > ++class extents { + public: +- typedef extents_base base_type; +- +- typedef typename base_type::key_type key_type; +- typedef base_type value_type; +- typedef typename base_type::range_type range_type; +- typedef typename base_type::mapped_type mapped_type; +- typedef typename base_type::mapped_value_type mapped_value_type; +- typedef typename base_type::table_type table_type; +- +- static const key_type mask_bits = MaskBits; +- static const key_type table_bits = TableBits; +- static const key_type table_size = TableSize; +- +- using base_type::at; +- using base_type::sizeof_data; ++ typedef Address key_type; // start address ++ typedef Value mapped_value_type; // The value mapped to the ip range ++ typedef std::pair mapped_type; // End address, value mapped to ip range ++ typedef std::map range_map_type; // The map itself + + extents(); ++ ~extents(); + +- bool is_equal_range(key_type first, key_type last, const mapped_value_type& val) const; +- +- void insert(key_type pos, unsigned int mb, const mapped_value_type& val); ++ void insert(key_type address_start, key_type address_end, mapped_value_type value); ++ bool defined(key_type address_start, key_type address_end); ++ bool defined(key_type address); ++ key_type get_matching_key(key_type address_start, key_type address_end); // throws error on not defined. test with defined() ++ mapped_value_type at(key_type address_start, key_type address_end); // throws error on not defined. test with defined() ++ mapped_value_type at(key_type address); // throws error on not defined. test with defined() ++ unsigned int sizeof_data() const; + +- base_type* data() { return this; } ++ range_map_type range_map; + }; + +-template +-extents_base::extents_base(key_type pos, unsigned int mb, mapped_value_type val) : +- mask_bits(mb), position(pos) { +- std::fill(table.begin(), table.end(), mapped_type(NULL, mapped_value_type())); ++/////////////////////////////////////// ++// CONSTRUCTOR [PLACEHOLDER] ++/////////////////////////////////////// ++template ++extents::extents() { ++ //nothing to do ++ return; + } + +-template +-extents_base::extents_base(extents_base* parent, typename table_type::const_iterator itr) : +- mask_bits(parent->mask_bits - TableBits), position(parent->partition_pos(itr)) { +- std::fill(table.begin(), table.end(), mapped_type(NULL, itr->second)); ++/////////////////////////////////////// ++// DESTRUCTOR [PLACEHOLDER] ++/////////////////////////////////////// ++template ++extents::~extents() { ++ //nothing to do. map destructor can handle cleanup. ++ return; + } + +-template +-extents::extents() : +- base_type(key_type(), mask_bits - table_bits, mapped_value_type()) +-{ +-} ++////////////////////////////////////////////////////////////////////////////////// ++// INSERT O(log N) assuming no overlapping ranges ++///////////////////////////////////////////////////////////////////////////////// ++template ++void extents::insert(key_type address_start, key_type address_end, mapped_value_type value) { ++ //we allow overlap ranges though not 100% overlap but only if mapped values are the same. first remove any overlap range that has a different value. ++ typename range_map_type::iterator iter = range_map.upper_bound(address_start); ++ if( iter != range_map.begin() ) { iter--; } ++ bool ignore_due_to_total_overlap = false; ++ while( iter->first <= address_end && iter != range_map.end() ) { ++ key_type delete_key = iter->first; ++ bool do_delete_due_to_overlap = iter->first <= address_end && (iter->second).first >= address_start && (iter->second).second != value; ++ bool do_delete_due_to_total_overlap = address_start <= iter->first && address_end >= (iter->second).first; ++ iter++; ++ if(do_delete_due_to_overlap || do_delete_due_to_total_overlap) { ++ range_map.erase (delete_key); ++ } ++ else { ++ ignore_due_to_total_overlap = ignore_due_to_total_overlap || ( iter->first <= address_start && (iter->second).first >= address_end ); ++ } ++ } + +-template +-extents_base::~extents_base() { +- for (typename table_type::const_iterator itr = table.begin(), last = table.end(); itr != last; itr++) +- delete itr->first; ++ if(!ignore_due_to_total_overlap) { ++ mapped_type entry; ++ entry.first = address_end; ++ entry.second = value; ++ range_map.insert( std::pair(address_start, entry) ); ++ } + } + +-template +-unsigned int +-extents_base::sizeof_data() const { +- unsigned int sum = sizeof(*this); +- +- for (typename table_type::const_iterator itr = table.begin(), last = table.end(); itr != last; itr++) +- if (itr->first != NULL) +- sum += itr->first->sizeof_data(); +- +- return sum; ++////////////////////////////////////////////////////////////////////// ++// DEFINED O(log N) assuming no overlapping ranges ++////////////////////////////////////////////////////////////////////// ++template ++bool extents::defined(key_type address_start, key_type address_end) { ++ bool defined = false; ++ typename range_map_type::iterator iter = range_map.upper_bound(address_start); ++ if( iter != range_map.begin() ) { iter--; } ++ while( iter->first <= address_end && !defined && iter != range_map.end() ) { ++ defined = iter->first <= address_end && (iter->second).first >= address_start; ++ iter++; ++ } ++ return defined; + } +- +-template +-void +-extents::insert(key_type pos, unsigned int mb, const mapped_value_type& val) { +- key_type mask = ~key_type() << mb; +- +- base_type::insert(pos & mask, mb, val); ++template ++bool extents::defined(key_type address) { ++ return defined(address, address); + } + +-template +-void +-extents_base::insert(key_type pos, unsigned int mb, const mapped_value_type& val) { +- // RESTRICTED +- typename table_type::iterator first = partition_at(pos); +- typename table_type::iterator last = partition_at(pos) + mask_distance(mb) + 1; +- +- if (mb < mask_bits) { +- if (first->first == NULL) +- first->first = new extents_base(this, first); ++////////////////////////////////////////////////////////////////////// ++// GET_MATCHING_KEY O(log N) assuming no overlapping ranges ++////////////////////////////////////////////////////////////////////// ++template ++typename extents::key_type extents::get_matching_key(key_type address_start, key_type address_end) { ++ key_type key; ++ bool defined = false; ++ typename range_map_type::iterator iter = range_map.upper_bound(address_start); ++ if( iter != range_map.begin() ) { iter--; } ++ while( iter->first <= address_end && !defined && iter != range_map.end() ) { ++ defined = iter->first <= address_end && (iter->second).first >= address_start; ++ if(defined) ++ key = iter->first; + +- first->first->insert(pos, mb, val); +- return; ++ iter++; + } +- +- while (first != last) { +- if (first->first != NULL) { +- delete first->first; +- first->first = NULL; +- } +- +- (first++)->second = val; ++ // this will cause exception to be thrown ++ if(!defined) { ++ std::out_of_range e("nothing defined for specified key"); ++ throw e; + } ++ return key; + } + +-template +-bool +-extents::is_equal_range(key_type first, key_type last, const mapped_value_type& val) const { +- // RESTRICTED +- first = std::max(first, key_type()); +- last = std::min(last, key_type() + (~key_type() >> (sizeof(key_type) * 8 - MaskBits))); +- +- if (first <= last) +- return base_type::is_equal_range(first, last, val); +- else +- return true; ++////////////////////////////////////////////////////////////////////// ++// AT O(log N) assuming no overlapping ranges ++////////////////////////////////////////////////////////////////////// ++template ++typename extents::mapped_value_type extents::at(key_type address_start, key_type address_end) { ++ key_type key = get_matching_key(address_start, address_end); ++ mapped_type entry = range_map.at(key); ++ return entry.second; + } +- +-template +-bool +-extents_base::is_equal_range(key_type key_first, key_type key_last, const mapped_value_type& val) const { +- // RESTRICTED +- typename table_type::const_iterator first = partition_at(key_first); +- typename table_type::const_iterator last = partition_at(key_last) + 1; +- +- do { +- // std::cout << "shift_amount " << key_first << ' ' << key_last << std::endl; +- +- if (first->first == NULL && val != first->second) +- return false; +- +- if (first->first != NULL && !first->first->is_equal_range(std::max(key_first, partition_pos(first)), +- std::min(key_last, partition_pos(first + 1) - 1), val)) +- return false; +- +- } while (++first != last); +- +- return true; ++template ++typename extents::mapped_value_type extents::at(key_type address) { ++ return at(address, address); + } + +-// Assumes 'key' is within the range of the range. +-template +-const typename extents_base::mapped_value_type& +-extents_base::at(key_type key) const { +- typename table_type::const_iterator itr = partition_at(key); +- +- while (itr->first != NULL) +- itr = itr->first->partition_at(key); +- +- return itr->second; ++////////////////////////////////////////////////////////////////////// ++// SIZEOF_DATA O(1) ++////////////////////////////////////////////////////////////////////// ++template ++unsigned int extents::sizeof_data() const { ++ // we don't know overhead on map, so this won't be accurate. just estimate. ++ unsigned int entry_size = sizeof(key_type) + sizeof(mapped_type); ++ return entry_size * range_map.size(); + } + ++ + } + + #endif 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 000000000..45f92524f --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch @@ -0,0 +1,47 @@ +From 4a5ed3897e772c75929b376b08985d844898b619 Mon Sep 17 00:00:00 2001 +From: chros +Date: Tue, 12 Dec 2017 15:19:51 +0000 +Subject: [PATCH] Disable extents test to pass TravisCI (See #11) + +--- + test/torrent/utils/test_extents.cc | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc +index 6ac5a57d..d6b8d11d 100644 +--- a/test/torrent/utils/test_extents.cc ++++ b/test/torrent/utils/test_extents.cc +@@ -16,10 +16,11 @@ void + ExtentsTest::tearDown() { + } + +-typedef torrent::extents extent_type_1; ++//typedef torrent::extents extent_type_1; ++typedef torrent::extents extent_type_1; + + // typedef torrent::extents extent_type_3; +- ++/* + template + bool + verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) { +@@ -46,11 +47,11 @@ static const int val_basic_1[] = {1, 0, 1}; + + // static const uint32_t idx_basic_2[] = {0, 1, 16, 255, 256, 256}; + // static const int val_basic_2[] = {1, 0, 2, 1}; +- ++*/ + void + ExtentsTest::test_basic() { + extent_type_1 extent_1; +- ++/* + // Test empty. + CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty)); + +@@ -68,4 +69,5 @@ ExtentsTest::test_basic() { + // extent_1.insert(38, 3, 2); + + // CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_2, val_basic_2)); ++*/ + } 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 000000000..645cf0f99 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch @@ -0,0 +1,30 @@ +From da7db7db29a8488e29d3b0f02906c5db379d4b6d Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Thu, 7 Jun 2018 13:18:03 +0900 +Subject: [PATCH] Bumped version to 0.13.7. + +--- + configure.ac | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index a6df6b80..5b1ea237 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,12 +1,12 @@ +-AC_INIT(libtorrent, 0.13.6, sundell.software@gmail.com) ++AC_INIT(libtorrent, 0.13.7, sundell.software@gmail.com) + + LT_INIT([disable-static]) + + dnl Find a better way to do this +-AC_DEFINE(PEER_NAME, "-lt0D60-", Identifier that is part of the default peer id) +-AC_DEFINE(PEER_VERSION, "lt\x0D\x60", 4 byte client and version identifier for DHT) ++AC_DEFINE(PEER_NAME, "-lt0D70-", Identifier that is part of the default peer id) ++AC_DEFINE(PEER_VERSION, "lt\x0D\x70", 4 byte client and version identifier for DHT) + +-LIBTORRENT_CURRENT=19 ++LIBTORRENT_CURRENT=20 + LIBTORRENT_REVISION=0 + LIBTORRENT_AGE=0 + 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 000000000..eaec545bb --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch @@ -0,0 +1,105 @@ +From dbf6abfd6f905b9218465d15eebec7eedaaed6b0 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Tue, 20 Dec 2016 19:51:02 +0900 +Subject: [PATCH] Added support for openssl 1.1. + +--- + configure.ac | 4 ++++ + src/utils/diffie_hellman.cc | 36 ++++++++++++++++++++++++++++++++++-- + 2 files changed, 38 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 5b1ea237..b885714d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -71,12 +71,15 @@ AC_ARG_ENABLE(openssl, + [ --disable-openssl Don't use OpenSSL's SHA1 implementation.], + [ + if test "$enableval" = "yes"; then ++dnl move to scripts. + PKG_CHECK_MODULES(OPENSSL, libcrypto, + CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS"; + LIBS="$LIBS $OPENSSL_LIBS") + + AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.) + AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.) ++ AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)]) ++ + else + AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.) + fi +@@ -87,6 +90,7 @@ AC_ARG_ENABLE(openssl, + + AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.) + AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.) ++ AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)]) + ] + ) + +diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc +index aa653d45..7ec13165 100644 +--- a/src/utils/diffie_hellman.cc ++++ b/src/utils/diffie_hellman.cc +@@ -54,11 +54,23 @@ DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength, + m_secret(NULL), m_size(0) { + + #ifdef USE_OPENSSL ++ + m_dh = DH_new(); ++ ++#ifdef USE_OPENSSL_1_1 ++ BIGNUM * const dh_p = BN_bin2bn(prime, primeLength, NULL); ++ BIGNUM * const dh_g = BN_bin2bn(generator, generatorLength, NULL); ++ ++ if (dh_p == NULL || dh_g == NULL || ++ !DH_set0_pqg(m_dh, dh_p, NULL, dh_g)) ++ throw internal_error("Could not generate Diffie-Hellman parameters"); ++#else + m_dh->p = BN_bin2bn(prime, primeLength, NULL); + m_dh->g = BN_bin2bn(generator, generatorLength, NULL); ++#endif + + DH_generate_key(m_dh); ++ + #else + throw internal_error("Compiled without encryption support."); + #endif +@@ -74,7 +86,19 @@ DiffieHellman::~DiffieHellman() { + bool + DiffieHellman::is_valid() const { + #ifdef USE_OPENSSL ++ if (m_dh == NULL) ++ return false; ++ ++#ifdef USE_OPENSSL_1_1 ++ const BIGNUM *pub_key; ++ ++ DH_get0_key(m_dh, &pub_key, NULL); ++ ++ return pub_key != NULL; ++#else + return m_dh != NULL && m_dh->pub_key != NULL; ++#endif ++ + #else + return false; + #endif +@@ -103,8 +127,16 @@ DiffieHellman::store_pub_key(unsigned char* dest, unsigned int length) { + #ifdef USE_OPENSSL + std::memset(dest, 0, length); + +- if ((int)length >= BN_num_bytes(m_dh->pub_key)) +- BN_bn2bin(m_dh->pub_key, dest + length - BN_num_bytes(m_dh->pub_key)); ++ const BIGNUM *pub_key; ++ ++#ifdef USE_OPENSSL_1_1 ++ DH_get0_key(m_dh, &pub_key, NULL); ++#else ++ pub_key = m_dh->pub_key; ++#endif ++ ++ if ((int)length >= BN_num_bytes(pub_key)) ++ BN_bn2bin(pub_key, dest + length - BN_num_bytes(pub_key)); + #endif + } + 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 000000000..6625fb55c --- /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 @@ +From c2ec5e0fb8ce7a0df513b5f4086e23d92049ef0e Mon Sep 17 00:00:00 2001 +From: Stephen Shkardoon +Date: Mon, 25 Jun 2018 20:05:18 +1200 +Subject: [PATCH] Use AC_COMPILE instead of AC_RUN to check for execinfo.h + +This way enables cross compiling, since we don't need to run anything +during the configure script. +--- + scripts/common.m4 | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/common.m4 b/scripts/common.m4 +index ff023928..b6d051f5 100644 +--- a/scripts/common.m4 ++++ b/scripts/common.m4 +@@ -153,7 +153,7 @@ dnl Need to fix this so that it uses the stuff defined by the system. + AC_DEFUN([TORRENT_CHECK_EXECINFO], [ + AC_MSG_CHECKING(for execinfo.h) + +- AC_RUN_IFELSE([AC_LANG_SOURCE([ ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ + #include + int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;} + ])], 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 000000000..974f992de --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch @@ -0,0 +1,46 @@ +From b0fb874a8921fa4ba2ea0923d779fae8f70c82b1 Mon Sep 17 00:00:00 2001 +From: Stephen Shkardoon +Date: Thu, 21 Jun 2018 14:38:30 +1200 +Subject: [PATCH] Modify configure to prevent unnecessary kqueue checks + +By only running the TORRENT_CHECK_KQUEUE_SOCKET_ONLY check if kqueue support +is already detected, we increase the number of platforms that we can +cross compile on. +Otherwise, the cross compilation fails due to TORRENT_CHECK_KQUEUE_SOCKET_ONLY +using AC_RUN_IFELSE, which fails during cross compilation. +--- + scripts/checks.m4 | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/scripts/checks.m4 b/scripts/checks.m4 +index 8d77fc5e..c9333561 100644 +--- a/scripts/checks.m4 ++++ b/scripts/checks.m4 +@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [ + [ + AC_DEFINE(USE_KQUEUE, 1, Use kqueue.) + AC_MSG_RESULT(yes) ++ TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ], [ + AC_MSG_RESULT(no) + ]) +@@ -137,7 +138,6 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [ + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ]) + ]) +@@ -149,11 +149,9 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ], [ + TORRENT_CHECK_KQUEUE +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ]) + ]) + 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 000000000..562cdae7a --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch @@ -0,0 +1,58 @@ +From 4ff83fc53b2c7462b02f804ee20414d85944e3c9 Mon Sep 17 00:00:00 2001 +From: chros +Date: Sun, 14 May 2017 19:36:09 +0100 +Subject: [PATCH] Display info on failed tracker bencode parsing (See #9) + +--- + rak/string_manip.h | 20 ++++++++++++++++++++ + src/tracker/tracker_http.cc | 6 ++++-- + 2 files changed, 24 insertions(+), 2 deletions(-) + +diff --git a/rak/string_manip.h b/rak/string_manip.h +index f8d3f590..68614d2a 100644 +--- a/rak/string_manip.h ++++ b/rak/string_manip.h +@@ -371,6 +371,26 @@ is_all_name(const Sequence& src) { + return is_all_name(src.begin(), src.end()); + } + ++template ++std::string ++sanitize(Iterator first, Iterator last) { ++ std::string dest; ++ for (; first != last; ++first) { ++ if (std::isprint(*first) && *first != '\r' && *first != '\n' && *first != '\t') ++ dest += *first; ++ else ++ dest += " "; ++ } ++ ++ return dest; ++} ++ ++template ++std::string ++sanitize(const Sequence& src) { ++ return trim(sanitize(src.begin(), src.end())); ++} ++ + } + + #endif +diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc +index 553f922c..b6d9e0ac 100644 +--- a/src/tracker/tracker_http.cc ++++ b/src/tracker/tracker_http.cc +@@ -288,8 +288,10 @@ TrackerHttp::receive_done() { + Object b; + *m_data >> b; + +- if (m_data->fail()) +- return receive_failed("Could not parse bencoded data"); ++ if (m_data->fail()) { ++ std::string dump = m_data->str(); ++ return receive_failed("Could not parse bencoded data: " + rak::sanitize(dump).substr(0,99)); ++ } + + if (!b.is_map()) + return receive_failed("Root not a bencoded map"); 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 000000000..7a8c9aa5a --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch @@ -0,0 +1,60 @@ +From 2f197be69057f793d29272b90300f74d0b588d51 Mon Sep 17 00:00:00 2001 +From: chros +Date: Mon, 15 May 2017 19:24:33 +0100 +Subject: [PATCH] Strip tags also when displaying info on failed tracker + bencode parsing (See #9) + +--- + rak/string_manip.h | 25 +++++++++++++++++++++++++ + src/tracker/tracker_http.cc | 2 +- + 2 files changed, 26 insertions(+), 1 deletion(-) + +diff --git a/rak/string_manip.h b/rak/string_manip.h +index 68614d2a..ae867c98 100644 +--- a/rak/string_manip.h ++++ b/rak/string_manip.h +@@ -391,6 +391,31 @@ sanitize(const Sequence& src) { + return trim(sanitize(src.begin(), src.end())); + } + ++template ++std::string striptags(Iterator first, Iterator last) { ++ bool copychar = true; ++ std::string dest; ++ ++ for (; first != last; ++first) { ++ if (std::isprint(*first) && *first == '<') { ++ copychar = false; ++ } else if (std::isprint(*first) && *first == '>') { ++ copychar = true; ++ continue; ++ } ++ ++ if (copychar) ++ dest += *first; ++ } ++ ++ return dest; ++} ++ ++template ++std::string striptags(const Sequence& src) { ++ return striptags(src.begin(), src.end()); ++} ++ + } + + #endif +diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc +index b6d9e0ac..eefe5a17 100644 +--- a/src/tracker/tracker_http.cc ++++ b/src/tracker/tracker_http.cc +@@ -290,7 +290,7 @@ TrackerHttp::receive_done() { + + if (m_data->fail()) { + std::string dump = m_data->str(); +- return receive_failed("Could not parse bencoded data: " + rak::sanitize(dump).substr(0,99)); ++ return receive_failed("Could not parse bencoded data: " + rak::sanitize(rak::striptags(dump)).substr(0,99)); + } + + if (!b.is_map()) 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 000000000..f4776247d --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch @@ -0,0 +1,45 @@ +From 0e86289a8bb5672781e508683bb28aebf9995127 Mon Sep 17 00:00:00 2001 +From: lps-rocks +Date: Mon, 4 Mar 2019 05:03:47 -0500 +Subject: [PATCH] Switch to C++11 MRT RNG for random bytes + +Switching to a better RNG for generating strings will prevent the common peerID collisions the rTorrent client has been seeing for YEARS in #440 and #318. +--- + rak/string_manip.h | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/rak/string_manip.h b/rak/string_manip.h +index ae867c98..1a09c377 100644 +--- a/rak/string_manip.h ++++ b/rak/string_manip.h +@@ -39,9 +39,13 @@ + + #include + #include ++#include + #include ++#include + #include + #include ++#include ++ + + namespace rak { + +@@ -312,11 +316,13 @@ transform_hex_str(const Sequence& seq) { + template + Sequence + generate_random(size_t length) { ++ std::random_device rd; ++ std::mt19937 mt(rd()); ++ using bytes_randomizer = std::independent_bits_engine; ++ bytes_randomizer bytes(mt); + Sequence s; + s.reserve(length); +- +- std::generate_n(std::back_inserter(s), length, &::random); +- ++ std::generate_n(std::back_inserter(s), length, std::ref(bytes)); + return s; + } + 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 000000000..1d4cc3e33 --- /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 @@ +From bf35c5f3d4e458a671fdc3c382f4fa06ecaeb119 Mon Sep 17 00:00:00 2001 +From: Vladyslav Movchan +Date: Sat, 3 Nov 2018 19:52:56 +0200 +Subject: [PATCH] Prevent loss of 'm_ipv6_socket' attribute which led to + execution of setsockopt(..., IPPROTO_IP, IP_TOS, ...) on IPv6 socket + +--- + src/net/socket_fd.cc | 4 ++-- + src/net/socket_fd.h | 1 + + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/net/socket_fd.cc b/src/net/socket_fd.cc +index 54cb6ded..f04059f6 100644 +--- a/src/net/socket_fd.cc ++++ b/src/net/socket_fd.cc +@@ -251,7 +251,7 @@ SocketFd::accept(rak::socket_address* sa) { + socklen_t len = sizeof(rak::socket_address); + + if (sa == NULL) { +- return SocketFd(::accept(m_fd, NULL, &len)); ++ return SocketFd(::accept(m_fd, NULL, &len), m_ipv6_socket); + } + + int fd = ::accept(m_fd, sa->c_sockaddr(), &len); +@@ -260,7 +260,7 @@ SocketFd::accept(rak::socket_address* sa) { + *sa = sa->sa_inet6()->normalize_address(); + } + +- return SocketFd(fd); ++ return SocketFd(fd, m_ipv6_socket); + } + + // unsigned int +diff --git a/src/net/socket_fd.h b/src/net/socket_fd.h +index ca765e88..2329b4e9 100644 +--- a/src/net/socket_fd.h ++++ b/src/net/socket_fd.h +@@ -51,6 +51,7 @@ public: + + SocketFd() : m_fd(-1) {} + explicit SocketFd(int fd) : m_fd(fd) {} ++ SocketFd(int fd, bool ipv6_socket) : m_fd(fd), m_ipv6_socket(ipv6_socket) {} + + bool is_valid() const { return m_fd >= 0; } + 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 000000000..4bb1ed21c --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch @@ -0,0 +1,27 @@ +From 1890bde5c051d932d1b2940e815d0c82964c474c Mon Sep 17 00:00:00 2001 +From: Gleb Smirnoff +Date: Tue, 2 Oct 2018 18:57:43 -0700 +Subject: [PATCH] If during socket creation AF_INET6 failes initialize sockaddr + as AF_INET. Otherwise any bind(2) would fail due to sockaddr address family + not matching socket address family. + +--- + src/net/listen.cc | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/net/listen.cc b/src/net/listen.cc +index da1c2e84..d424e94c 100644 +--- a/src/net/listen.cc ++++ b/src/net/listen.cc +@@ -75,7 +75,10 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre + + // TODO: Temporary until we refactor: + if (bindAddress->family() == 0) { +- sa.sa_inet6()->clear(); ++ if (m_ipv6_socket) ++ sa.sa_inet6()->clear(); ++ else ++ sa.sa_inet()->clear(); + } else { + sa.copy(*bindAddress, bindAddress->length()); + } 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 000000000..a33a0103b --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch @@ -0,0 +1,29 @@ +From cbd946b6cad8c93b3d39ab4f338b3640f684cbfc Mon Sep 17 00:00:00 2001 +From: Adam Fontenot +Date: Sat, 7 Jul 2018 16:52:07 -0700 +Subject: [PATCH] Fixes https://github.com/rakshasa/rtorrent/issues/731 + +--- + src/tracker/tracker_http.cc | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc +index eefe5a17..1bf94107 100644 +--- a/src/tracker/tracker_http.cc ++++ b/src/tracker/tracker_http.cc +@@ -145,13 +145,13 @@ TrackerHttp::send_state(int state) { + if (!localAddress->is_address_any()) + s << "&ip=" << localAddress->address_str(); + +- if (localAddress->is_address_any() || localAddress->family() != rak::socket_address::pf_inet6) { ++ if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) { + rak::socket_address local_v6; + if (get_local_address(rak::socket_address::af_inet6, &local_v6)) + s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str()); + } + +- if (localAddress->is_address_any() || localAddress->family() != rak::socket_address::pf_inet) { ++ if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) { + rak::socket_address local_v4; + if (get_local_address(rak::socket_address::af_inet, &local_v4)) + s << "&ipv4=" << local_v4.address_str(); 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 000000000..6ef5f1ad4 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch @@ -0,0 +1,40 @@ +From d49316117401cff4045b1d1194cec60909e45555 Mon Sep 17 00:00:00 2001 +From: chros +Date: Sun, 13 May 2018 11:34:33 +0100 +Subject: [PATCH] Fix honoring throttle.min_peers* settings in rtorrent (See + #13) + +--- + src/download/download_main.cc | 17 ++++++----------- + 1 file changed, 6 insertions(+), 11 deletions(-) + +diff --git a/src/download/download_main.cc b/src/download/download_main.cc +index 48222c38..efe91d66 100644 +--- a/src/download/download_main.cc ++++ b/src/download/download_main.cc +@@ -355,19 +355,14 @@ DownloadMain::receive_tracker_success() { + + void + DownloadMain::receive_tracker_request() { +- bool should_stop = false; +- bool should_start = false; ++ if (info()->is_pex_enabled() && info()->size_pex() > 0 ++ || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) { + +- if (info()->is_pex_enabled() && info()->size_pex() > 0) +- should_stop = true; +- +- if (connection_list()->size() + peer_list()->available_list()->size() / 2 < connection_list()->min_size()) +- should_start = true; +- +- if (should_stop) + m_tracker_controller->stop_requesting(); +- else if (should_start) +- m_tracker_controller->start_requesting(); ++ return; ++ } ++ ++ m_tracker_controller->start_requesting(); + } + + struct SocketAddressCompact_less { 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 000000000..7108507a1 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch @@ -0,0 +1,22 @@ +From 9fd2f35f86397b9259e0c9b7c54444c0ec3c8965 Mon Sep 17 00:00:00 2001 +From: adam +Date: Mon, 26 Feb 2018 16:04:34 +0200 +Subject: [PATCH] increase piece length max + +--- + src/download/download_constructor.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/download/download_constructor.cc b/src/download/download_constructor.cc +index 1bb261bd..67ef4276 100644 +--- a/src/download/download_constructor.cc ++++ b/src/download/download_constructor.cc +@@ -157,7 +157,7 @@ DownloadConstructor::parse_info(const Object& b) { + } else { + chunkSize = b.get_key_value("piece length"); + +- if (chunkSize <= (1 << 10) || chunkSize > (128 << 20)) ++ if (chunkSize <= (1 << 10) || chunkSize > (128 << 22)) + throw input_error("Torrent has an invalid \"piece length\"."); + } + 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 000000000..f864d23c3 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch @@ -0,0 +1,22 @@ +From b263b347f14b9d0ca54d04ca92367a98d791dc17 Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Sun, 9 Jun 2019 14:53:32 +0900 +Subject: [PATCH] Set max piece size 512mb. + +--- + src/download/download_constructor.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/download/download_constructor.cc b/src/download/download_constructor.cc +index 67ef4276..1bf362fa 100644 +--- a/src/download/download_constructor.cc ++++ b/src/download/download_constructor.cc +@@ -157,7 +157,7 @@ DownloadConstructor::parse_info(const Object& b) { + } else { + chunkSize = b.get_key_value("piece length"); + +- if (chunkSize <= (1 << 10) || chunkSize > (128 << 22)) ++ if (chunkSize <= (1 << 10) || chunkSize > (512 << 20)) + throw input_error("Torrent has an invalid \"piece length\"."); + } + 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 000000000..0a06a2688 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch @@ -0,0 +1,22 @@ +From cdfb4381bedb278dabb8ca75c10858d16b895355 Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Sun, 9 Jun 2019 14:55:44 +0900 +Subject: [PATCH] Fixed compiler warning. + +--- + src/download/download_main.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/download/download_main.cc b/src/download/download_main.cc +index efe91d66..9a3f9df2 100644 +--- a/src/download/download_main.cc ++++ b/src/download/download_main.cc +@@ -355,7 +355,7 @@ DownloadMain::receive_tracker_success() { + + void + DownloadMain::receive_tracker_request() { +- if (info()->is_pex_enabled() && info()->size_pex() > 0 ++ if ((info()->is_pex_enabled() && info()->size_pex()) > 0 + || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) { + + m_tracker_controller->stop_requesting(); 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 000000000..0f183816c --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch @@ -0,0 +1,74 @@ +From 8934703edb5982661483eb8a29d76e6a726b5fe2 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Mon, 8 Jul 2019 19:37:06 +0200 +Subject: [PATCH] Added _GNU_SOURCE to fallocate test. (neheb) + +--- + scripts/checks.m4 | 10 ++++++---- + src/data/socket_file.cc | 1 + + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/scripts/checks.m4 b/scripts/checks.m4 +index c9333561..83be8461 100644 +--- a/scripts/checks.m4 ++++ b/scripts/checks.m4 +@@ -88,7 +88,6 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [ + [ + AC_DEFINE(USE_KQUEUE, 1, Use kqueue.) + AC_MSG_RESULT(yes) +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ], [ + AC_MSG_RESULT(no) + ]) +@@ -97,7 +96,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [ + AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [ + AC_MSG_CHECKING(whether kqueue supports pipes and ptys) + +- AC_RUN_IFELSE([AC_LANG_SOURCE([ ++ AC_LINK_IFELSE([AC_LANG_SOURCE([ + #include + #include + #include +@@ -138,6 +137,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [ + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE ++ TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ]) + ]) +@@ -149,9 +149,11 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE ++ TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ], [ + TORRENT_CHECK_KQUEUE ++ TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ]) + ]) + +@@ -172,8 +174,8 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ + AC_DEFUN([TORRENT_CHECK_FALLOCATE], [ + AC_MSG_CHECKING(for fallocate) + +- AC_TRY_LINK([#include +- #include ++ AC_TRY_LINK([#define _GNU_SOURCE ++ #include + ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0; + ], + [ +diff --git a/src/data/socket_file.cc b/src/data/socket_file.cc +index 4b4519ed..b359ef8e 100644 +--- a/src/data/socket_file.cc ++++ b/src/data/socket_file.cc +@@ -48,6 +48,7 @@ + #include + + #ifdef HAVE_FALLOCATE ++#define _GNU_SOURCE + #include + #endif + 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 000000000..ad9e45758 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch @@ -0,0 +1,293 @@ +From 856d42e2ca3c9810bf84a8bce219000e822540fa Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Fri, 12 Jul 2019 00:29:35 +0200 +Subject: [PATCH] Fixed diffie hellman implementation. + +--- + src/utils/diffie_hellman.cc | 137 ++++++++++++------------------------ + src/utils/diffie_hellman.h | 67 ++++-------------- + 2 files changed, 59 insertions(+), 145 deletions(-) + +diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc +index 7ec13165..d53a857b 100644 +--- a/src/utils/diffie_hellman.cc ++++ b/src/utils/diffie_hellman.cc +@@ -1,118 +1,79 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + ++#include "diffie_hellman.h" ++ ++#include "torrent/exceptions.h" ++ + #include +-#include + + #ifdef USE_OPENSSL ++#include + #include + #endif + +-#include "diffie_hellman.h" +-#include "torrent/exceptions.h" +- + namespace torrent { + +-#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +-DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength, +- const unsigned char *generator, int generatorLength) : +- m_secret(NULL), m_size(0) { +- + #ifdef USE_OPENSSL + +- m_dh = DH_new(); +- +-#ifdef USE_OPENSSL_1_1 +- BIGNUM * const dh_p = BN_bin2bn(prime, primeLength, NULL); +- BIGNUM * const dh_g = BN_bin2bn(generator, generatorLength, NULL); ++static void dh_free(void* dh) { DH_free(reinterpret_cast(dh)); } ++static DiffieHellman::dh_ptr dh_new() { return DiffieHellman::dh_ptr(reinterpret_cast(DH_new()), &dh_free); } ++static DH* dh_get(DiffieHellman::dh_ptr& dh) { return reinterpret_cast(dh.get()); } + +- if (dh_p == NULL || dh_g == NULL || +- !DH_set0_pqg(m_dh, dh_p, NULL, dh_g)) +- throw internal_error("Could not generate Diffie-Hellman parameters"); ++static bool ++dh_set_pg(DiffieHellman::dh_ptr& dh, BIGNUM* dh_p, BIGNUM* dh_g) { ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ return DH_set0_pqg(reinterpret_cast(dh.get()), dh_p, nullptr, dh_g); + #else +- m_dh->p = BN_bin2bn(prime, primeLength, NULL); +- m_dh->g = BN_bin2bn(generator, generatorLength, NULL); ++ reinterpret_cast(dh.get())->p = dh_p; ++ reinterpret_cast(dh.get())->g = dh_g; ++ return true; + #endif ++} + +- DH_generate_key(m_dh); +- ++static const BIGNUM* dh_get_pub_key(const DiffieHellman::dh_ptr& dh) { ++#if OPENSSL_VERSION_NUMBER >= 0x10100000L ++ const BIGNUM *pub_key; ++ DH_get0_key(reinterpret_cast(dh.get()), &pub_key, nullptr); ++ return pub_key; + #else +- throw internal_error("Compiled without encryption support."); ++ return dh != nullptr ? reinterpret_cast(dh.get())->pub_key : nullptr; + #endif +-}; ++} + +-DiffieHellman::~DiffieHellman() { +- delete [] m_secret; +-#ifdef USE_OPENSSL +- DH_free(m_dh); ++#else ++static DiffieHellman::dh_ptr dh_new() { throw internal_error("Compiled without encryption support."); } ++static void dh_free(void* dh) {} ++static void* dh_get_pub_key(const DiffieHellman::dh_ptr& dh) { return nullptr; } + #endif +-}; + +-bool +-DiffieHellman::is_valid() const { +-#ifdef USE_OPENSSL +- if (m_dh == NULL) +- return false; ++#pragma GCC diagnostic ignored "-Wdeprecated-declarations" ++DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength, ++ const unsigned char *generator, int generatorLength) : ++ m_dh(dh_new()), m_size(0) { + +-#ifdef USE_OPENSSL_1_1 +- const BIGNUM *pub_key; ++#ifdef USE_OPENSSL ++ BIGNUM* dh_p = BN_bin2bn(prime, primeLength, nullptr); ++ BIGNUM* dh_g = BN_bin2bn(generator, generatorLength, nullptr); + +- DH_get0_key(m_dh, &pub_key, NULL); ++ if (dh_p == nullptr || dh_g == nullptr || !dh_set_pg(m_dh, dh_p, dh_g)) ++ throw internal_error("Could not generate Diffie-Hellman parameters"); + +- return pub_key != NULL; +-#else +- return m_dh != NULL && m_dh->pub_key != NULL; ++ DH_generate_key(dh_get(m_dh)); + #endif ++}; + +-#else +- return false; +-#endif ++bool ++DiffieHellman::is_valid() const { ++ return dh_get_pub_key(m_dh) != nullptr; + } + + bool + DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length) { + #ifdef USE_OPENSSL +- BIGNUM* k = BN_bin2bn(pubkey, length, NULL); ++ BIGNUM* k = BN_bin2bn(pubkey, length, nullptr); + +- delete [] m_secret; +- m_secret = new char[DH_size(m_dh)]; +- +- m_size = DH_compute_key((unsigned char*)m_secret, k, m_dh); ++ m_secret.reset(new char[DH_size(dh_get(m_dh))]); ++ m_size = DH_compute_key(reinterpret_cast(m_secret.get()), k, dh_get(m_dh)); + + BN_free(k); + +@@ -124,16 +85,10 @@ DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length) + + void + DiffieHellman::store_pub_key(unsigned char* dest, unsigned int length) { +-#ifdef USE_OPENSSL + std::memset(dest, 0, length); + +- const BIGNUM *pub_key; +- +-#ifdef USE_OPENSSL_1_1 +- DH_get0_key(m_dh, &pub_key, NULL); +-#else +- pub_key = m_dh->pub_key; +-#endif ++#ifdef USE_OPENSSL ++ const BIGNUM *pub_key = dh_get_pub_key(m_dh); + + if ((int)length >= BN_num_bytes(pub_key)) + BN_bn2bin(pub_key, dest + length - BN_num_bytes(pub_key)); +diff --git a/src/utils/diffie_hellman.h b/src/utils/diffie_hellman.h +index 432542be..2cec5bee 100644 +--- a/src/utils/diffie_hellman.h ++++ b/src/utils/diffie_hellman.h +@@ -1,79 +1,38 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_DIFFIE_HELLMAN_H + #define LIBTORRENT_DIFFIE_HELLMAN_H + + #include "config.h" + ++#include + #include + +-#ifdef USE_OPENSSL +-#include +-#endif +- + namespace torrent { + + class DiffieHellman { + public: ++ typedef std::unique_ptr secret_ptr; ++ typedef std::unique_ptr dh_ptr; ++ + DiffieHellman(const unsigned char prime[], int primeLength, + const unsigned char generator[], int generatorLength); +- ~DiffieHellman(); + +- bool compute_secret(const unsigned char pubkey[], unsigned int length); +- void store_pub_key(unsigned char* dest, unsigned int length); ++ bool is_valid() const; + +- bool is_valid() const; ++ bool compute_secret(const unsigned char pubkey[], unsigned int length); ++ void store_pub_key(unsigned char* dest, unsigned int length); + +- unsigned int size() const { return m_size; } ++ unsigned int size() const { return m_size; } + +- const char* c_str() const { return m_secret; } +- std::string secret_str() const { return std::string(m_secret, m_size); } ++ const char* c_str() const { return m_secret.get(); } ++ std::string secret_str() const { return std::string(m_secret.get(), m_size); } + + private: + DiffieHellman(const DiffieHellman& dh); + DiffieHellman& operator = (const DiffieHellman& dh); + +-#ifdef USE_OPENSSL +- DH* m_dh; +-#else +- void* m_void; +-#endif +- char* m_secret; +- unsigned int m_size; ++ dh_ptr m_dh; ++ secret_ptr m_secret; ++ int m_size; + }; + + }; 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 000000000..66f43f0ce --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch @@ -0,0 +1,64 @@ +From 660bbc17e32c518c2727607ee5b73039c7109207 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Sat, 13 Jul 2019 00:07:43 +0200 +Subject: [PATCH] Increased max timeout for tracker requests. + +--- + src/torrent/tracker.h | 40 ++-------------------------------------- + 1 file changed, 2 insertions(+), 38 deletions(-) + +diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h +index 2b00ad47..a528ef6a 100644 +--- a/src/torrent/tracker.h ++++ b/src/torrent/tracker.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_TRACKER_H + #define LIBTORRENT_TRACKER_H + +@@ -148,8 +112,8 @@ protected: + + void set_group(uint32_t v) { m_group = v; } + +- void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 3600); } +- void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 1800); } ++ void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 8 * 3600); } ++ void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 4 * 3600); } + + int m_flags; + 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 000000000..885b1828d --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch @@ -0,0 +1,123 @@ +From efc75948253c1a8db482daabf45d9eabaaf4b099 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Wed, 17 Jul 2019 19:41:04 +0200 +Subject: [PATCH] Close log files when reusing a name. + +--- + src/torrent/utils/log.cc | 20 ++++++++++++++++---- + src/torrent/utils/log.h | 7 +++++++ + test/torrent/tracker_timeout_test.cc | 8 ++++---- + test/torrent/utils/log_test.cc | 12 ++++++------ + 4 files changed, 33 insertions(+), 14 deletions(-) + +diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc +index 58b563a6..5169a730 100644 +--- a/src/torrent/utils/log.cc ++++ b/src/torrent/utils/log.cc +@@ -294,12 +294,16 @@ log_open_output(const char* name, log_slot slot) { + throw input_error("Cannot open more than 64 log output handlers."); + } + +- if (log_find_output_name(name) != log_outputs.end()) { +- pthread_mutex_unlock(&log_mutex); +- throw input_error("Log name already used."); ++ log_output_list::iterator itr = log_find_output_name(name); ++ ++ if (itr == log_outputs.end()) { ++ log_outputs.push_back(std::make_pair(name, slot)); ++ } else { ++ // by replacing the "write" slot binding, the old file gets closed ++ // (handles are shared pointers) ++ itr->second = slot; + } + +- log_outputs.push_back(std::make_pair(name, slot)); + log_rebuild_cache(); + + pthread_mutex_unlock(&log_mutex); +@@ -307,6 +311,14 @@ log_open_output(const char* name, log_slot slot) { + + void + log_close_output(const char* name) { ++ pthread_mutex_lock(&log_mutex); ++ ++ log_output_list::iterator itr = log_find_output_name(name); ++ ++ if (itr != log_outputs.end()) ++ log_outputs.erase(itr); ++ ++ pthread_mutex_unlock(&log_mutex); + } + + void +diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h +index a053d6ec..430bda5e 100644 +--- a/src/torrent/utils/log.h ++++ b/src/torrent/utils/log.h +@@ -229,6 +229,7 @@ void log_cleanup() LIBTORRENT_EXPORT; + + void log_open_output(const char* name, log_slot slot) LIBTORRENT_EXPORT; + void log_close_output(const char* name) LIBTORRENT_EXPORT; ++void log_close_output_str(const std::string name) LIBTORRENT_EXPORT; + + void log_add_group_output(int group, const char* name) LIBTORRENT_EXPORT; + void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT; +@@ -240,6 +241,12 @@ void log_open_file_output(const char* name, const char* filename) LIBTORR + void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT; + log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT; + ++// ++// Implementation: ++// ++ ++inline void log_close_output_str(const std::string name) { log_close_output(name.c_str()); } ++ + } + + #endif +diff --git a/test/torrent/tracker_timeout_test.cc b/test/torrent/tracker_timeout_test.cc +index 081b9301..cd060006 100644 +--- a/test/torrent/tracker_timeout_test.cc ++++ b/test/torrent/tracker_timeout_test.cc +@@ -29,13 +29,13 @@ tracker_timeout_test::test_set_timeout() { + + tracker.set_new_normal_interval(100); + CPPUNIT_ASSERT(tracker.normal_interval() == 600); +- tracker.set_new_normal_interval(4000); +- CPPUNIT_ASSERT(tracker.normal_interval() == 3600); ++ tracker.set_new_normal_interval(8 * 4000); ++ CPPUNIT_ASSERT(tracker.normal_interval() == 8 * 3600); + + tracker.set_new_min_interval(100); + CPPUNIT_ASSERT(tracker.min_interval() == 300); +- tracker.set_new_min_interval(4000); +- CPPUNIT_ASSERT(tracker.min_interval() == 1800); ++ tracker.set_new_min_interval(4 * 4000); ++ CPPUNIT_ASSERT(tracker.min_interval() == 4 * 3600); + } + + void +diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc +index 9b99c245..24c22b59 100644 +--- a/test/torrent/utils/log_test.cc ++++ b/test/torrent/utils/log_test.cc +@@ -75,13 +75,13 @@ utils_log_test::test_output_open() { + // Test inserting duplicate names, should catch. + // CPPUNIT_ASSERT_THROW(torrent::log_open_output("test_output_1", torrent::log_slot());, torrent::input_error); + +- try { +- torrent::log_open_output("test_output_1", torrent::log_slot()); +- } catch (torrent::input_error& e) { +- return; +- } ++ // try { ++ // torrent::log_open_output("test_output_1", torrent::log_slot()); ++ // } catch (torrent::input_error& e) { ++ // return; ++ // } + +- CPPUNIT_ASSERT(false); ++ // CPPUNIT_ASSERT(false); + + // Test more than 64 entries. + } 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 000000000..ffe6b3f22 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch @@ -0,0 +1,30 @@ +From 7faa9c58ce098bbdeff83b6add72f3075b47881d Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Fri, 19 Jul 2019 13:38:12 +0200 +Subject: [PATCH] Bumped to version 0.13.8. + +--- + configure.ac | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index b885714d..4ed08124 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,12 +1,12 @@ +-AC_INIT(libtorrent, 0.13.7, sundell.software@gmail.com) ++AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com) + + LT_INIT([disable-static]) + + dnl Find a better way to do this +-AC_DEFINE(PEER_NAME, "-lt0D70-", Identifier that is part of the default peer id) +-AC_DEFINE(PEER_VERSION, "lt\x0D\x70", 4 byte client and version identifier for DHT) ++AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id) ++AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT) + +-LIBTORRENT_CURRENT=20 ++LIBTORRENT_CURRENT=21 + LIBTORRENT_REVISION=0 + LIBTORRENT_AGE=0 + 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 000000000..c8884d856 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch @@ -0,0 +1,109 @@ +From 7667094274879fe158e718bf2765d35f82d924bd Mon Sep 17 00:00:00 2001 +From: nicholi +Date: Tue, 23 Jul 2019 23:59:16 -0700 +Subject: [PATCH] Allow logs to be appended rather than overwritten. + +--- + src/torrent/utils/log.cc | 13 +++++++++++++ + src/torrent/utils/log.h | 1 + + test/torrent/utils/log_test.cc | 35 ++++++++++++++++++++++++++++++++++ + test/torrent/utils/log_test.h | 2 ++ + 4 files changed, 51 insertions(+) + +diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc +index 5169a730..a900c109 100644 +--- a/src/torrent/utils/log.cc ++++ b/src/torrent/utils/log.cc +@@ -428,6 +428,19 @@ log_open_file_output(const char* name, const char* filename) { + std::placeholders::_3)); + } + ++void ++log_open_file_output_append(const char* name, const char* filename) { ++ std::shared_ptr outfile(new std::ofstream(filename, std::ofstream::out | std::ofstream::app)); ++ ++ if (!outfile->good()) ++ throw input_error("Could not open log file '" + std::string(filename) + "'."); ++ ++ log_open_output(name, std::bind(&log_file_write, outfile, ++ std::placeholders::_1, ++ std::placeholders::_2, ++ std::placeholders::_3)); ++} ++ + void + log_open_gz_file_output(const char* name, const char* filename) { + std::shared_ptr outfile(new log_gz_output(filename)); +diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h +index 430bda5e..531c8565 100644 +--- a/src/torrent/utils/log.h ++++ b/src/torrent/utils/log.h +@@ -238,6 +238,7 @@ void log_add_child(int group, int child) LIBTORRENT_EXPORT; + void log_remove_child(int group, int child) LIBTORRENT_EXPORT; + + void log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT; ++void log_open_file_output_append(const char* name, const char* filename) LIBTORRENT_EXPORT; + void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT; + log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT; + +diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc +index 24c22b59..aa13fff8 100644 +--- a/test/torrent/utils/log_test.cc ++++ b/test/torrent/utils/log_test.cc +@@ -155,3 +155,38 @@ utils_log_test::test_file_output() { + + CPPUNIT_ASSERT_MESSAGE(buffer, std::string(buffer).find("test_file") != std::string::npos); + } ++ ++void ++utils_log_test::test_file_output_append() { ++ std::string filename = "utils_log_test.XXXXXX"; ++ ++ mktemp(&*filename.begin()); ++ ++ torrent::log_open_file_output_append("test_file", filename.c_str()); ++ torrent::log_add_group_output(GROUP_PARENT_1, "test_file"); ++ ++ lt_log_print(GROUP_PARENT_1, "test_line_1"); ++ ++ torrent::log_cleanup(); // To ensure we flush the buffers. ++ ++ // re-open and write 2nd line ++ torrent::log_open_file_output_append("test_file", filename.c_str()); ++ torrent::log_add_group_output(GROUP_PARENT_1, "test_file"); ++ ++ lt_log_print(GROUP_PARENT_1, "test_line_2"); ++ ++ torrent::log_cleanup(); // To ensure we flush the buffers. ++ ++ std::ifstream temp_file(filename.c_str()); ++ ++ CPPUNIT_ASSERT(temp_file.good()); ++ ++ char buffer_line1[256]; ++ temp_file.getline(buffer_line1, 256); ++ ++ char buffer_line2[256]; ++ temp_file.getline(buffer_line2, 256); ++ ++ CPPUNIT_ASSERT_MESSAGE(buffer_line1, std::string(buffer_line1).find("test_line_1") != std::string::npos); ++ CPPUNIT_ASSERT_MESSAGE(buffer_line2, std::string(buffer_line2).find("test_line_2") != std::string::npos); ++} +diff --git a/test/torrent/utils/log_test.h b/test/torrent/utils/log_test.h +index 3a66cc24..d4cb3bc6 100644 +--- a/test/torrent/utils/log_test.h ++++ b/test/torrent/utils/log_test.h +@@ -10,6 +10,7 @@ class utils_log_test : public CppUnit::TestFixture { + CPPUNIT_TEST(test_print); + CPPUNIT_TEST(test_children); + CPPUNIT_TEST(test_file_output); ++ CPPUNIT_TEST(test_file_output_append); + CPPUNIT_TEST_SUITE_END(); + + public: +@@ -22,4 +23,5 @@ public: + void test_print(); + void test_children(); + void test_file_output(); ++ void test_file_output_append(); + }; 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 000000000..9859f954c --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch @@ -0,0 +1,101 @@ +From df54913c34c8b584d6d2072a65ad1590766780c5 Mon Sep 17 00:00:00 2001 +From: nicholi +Date: Fri, 26 Jul 2019 00:50:52 -0700 +Subject: [PATCH] Removed log append function. Added append parameter with + default value (false) to log_open_file functions. + +--- + src/torrent/utils/log.cc | 26 ++++++++------------------ + src/torrent/utils/log.h | 5 ++--- + test/torrent/utils/log_test.cc | 4 ++-- + 3 files changed, 12 insertions(+), 23 deletions(-) + +diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc +index a900c109..6c605474 100644 +--- a/src/torrent/utils/log.cc ++++ b/src/torrent/utils/log.cc +@@ -73,7 +73,7 @@ struct log_cache_entry { + }; + + struct log_gz_output { +- log_gz_output(const char* filename) { gz_file = gzopen(filename, "w"); } ++ log_gz_output(const char* filename, bool append) { gz_file = gzopen(filename, append ? "a" : "w"); } + ~log_gz_output() { if (gz_file != NULL) gzclose(gz_file); } + + bool is_valid() { return gz_file != Z_NULL; } +@@ -416,8 +416,11 @@ log_gz_file_write(std::shared_ptr& outfile, const char* data, siz + } + + void +-log_open_file_output(const char* name, const char* filename) { +- std::shared_ptr outfile(new std::ofstream(filename)); ++log_open_file_output(const char* name, const char* filename, bool append) { ++ std::ios_base::openmode mode = std::ofstream::out; ++ if (append) ++ mode |= std::ofstream::app; ++ std::shared_ptr outfile(new std::ofstream(filename, mode)); + + if (!outfile->good()) + throw input_error("Could not open log file '" + std::string(filename) + "'."); +@@ -429,21 +432,8 @@ log_open_file_output(const char* name, const char* filename) { + } + + void +-log_open_file_output_append(const char* name, const char* filename) { +- std::shared_ptr outfile(new std::ofstream(filename, std::ofstream::out | std::ofstream::app)); +- +- if (!outfile->good()) +- throw input_error("Could not open log file '" + std::string(filename) + "'."); +- +- log_open_output(name, std::bind(&log_file_write, outfile, +- std::placeholders::_1, +- std::placeholders::_2, +- std::placeholders::_3)); +-} +- +-void +-log_open_gz_file_output(const char* name, const char* filename) { +- std::shared_ptr outfile(new log_gz_output(filename)); ++log_open_gz_file_output(const char* name, const char* filename, bool append) { ++ std::shared_ptr outfile(new log_gz_output(filename, append)); + + if (!outfile->is_valid()) + throw input_error("Could not open log gzip file '" + std::string(filename) + "'."); +diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h +index 531c8565..0dfdc86b 100644 +--- a/src/torrent/utils/log.h ++++ b/src/torrent/utils/log.h +@@ -237,9 +237,8 @@ void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT; + void log_add_child(int group, int child) LIBTORRENT_EXPORT; + void log_remove_child(int group, int child) LIBTORRENT_EXPORT; + +-void log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT; +-void log_open_file_output_append(const char* name, const char* filename) LIBTORRENT_EXPORT; +-void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT; ++void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT; ++void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT; + log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT; + + // +diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc +index aa13fff8..9f975636 100644 +--- a/test/torrent/utils/log_test.cc ++++ b/test/torrent/utils/log_test.cc +@@ -162,7 +162,7 @@ utils_log_test::test_file_output_append() { + + mktemp(&*filename.begin()); + +- torrent::log_open_file_output_append("test_file", filename.c_str()); ++ torrent::log_open_file_output("test_file", filename.c_str(), false); + torrent::log_add_group_output(GROUP_PARENT_1, "test_file"); + + lt_log_print(GROUP_PARENT_1, "test_line_1"); +@@ -170,7 +170,7 @@ utils_log_test::test_file_output_append() { + torrent::log_cleanup(); // To ensure we flush the buffers. + + // re-open and write 2nd line +- torrent::log_open_file_output_append("test_file", filename.c_str()); ++ torrent::log_open_file_output("test_file", filename.c_str(), true); + torrent::log_add_group_output(GROUP_PARENT_1, "test_file"); + + lt_log_print(GROUP_PARENT_1, "test_line_2"); 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 000000000..6b1578bde --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch @@ -0,0 +1,7365 @@ +From b0f945e11d6afe43c917b58291c6fbcf5468a908 Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Fri, 23 Aug 2019 23:23:48 +0900 +Subject: [PATCH] Backport changes from feature-bind. (#200) + +--- + .dir-locals.el | 7 + + Makefile.am | 1 + + configure.ac | 40 +- + extra/corrupt_file.cc | 2 +- + rak/file_stat.h | 2 +- + rak/fs_stat.h | 2 +- + rak/partial_queue.h | 2 +- + rak/path.h | 2 +- + rak/priority_queue_default.h | 2 +- + rak/socket_address.h | 49 +- + rak/timer.h | 2 +- + scripts/checks.m4 | 4 +- + scripts/rak_cxx.m4 | 47 -- + scripts/ssl.m4 | 38 ++ + src/data/chunk_list.cc | 2 - + src/data/chunk_list.h | 2 +- + src/data/chunk_list_node.h | 2 +- + src/data/hash_check_queue.h | 2 +- + src/data/hash_queue.cc | 2 - + src/data/hash_queue.h | 2 +- + src/data/hash_queue_node.h | 4 +- + src/data/hash_torrent.cc | 2 - + src/data/hash_torrent.h | 4 +- + src/data/memory_chunk.h | 2 +- + src/data/socket_file.h | 2 +- + src/dht/dht_hash_map.h | 57 +- + src/download/chunk_selector.h | 2 +- + src/download/chunk_statistics.h | 2 +- + src/download/delegator.cc | 2 +- + src/download/delegator.h | 2 +- + src/download/download_constructor.h | 2 +- + src/globals.cc | 15 +- + src/globals.h | 36 -- + src/manager.cc | 36 -- + src/net/Makefile.am | 2 + + src/net/data_buffer.h | 2 +- + src/net/listen.cc | 40 +- + src/net/listen.h | 4 +- + src/net/protocol_buffer.h | 2 +- + src/net/socket_base.h | 2 +- + src/net/socket_fd.cc | 10 + + src/net/socket_fd.h | 6 + + src/net/socket_listen.cc | 137 +++++ + src/net/socket_listen.h | 46 ++ + src/net/socket_set.h | 2 +- + src/net/throttle_node.h | 2 +- + src/protocol/handshake.cc | 13 +- + src/protocol/handshake_manager.cc | 56 +- + src/protocol/handshake_manager.h | 40 +- + src/protocol/peer_connection_base.cc | 2 - + src/protocol/request_list.cc | 38 +- + src/torrent/Makefile.am | 1 + + src/torrent/common.h | 5 +- + src/torrent/connection_manager.h | 2 +- + src/torrent/data/download_data.h | 2 +- + src/torrent/data/file_list.cc | 2 - + src/torrent/data/transfer_list.h | 3 +- + src/torrent/download.cc | 4 +- + src/torrent/download/choke_group.cc | 2 +- + src/torrent/download/choke_group.h | 2 +- + src/torrent/download/choke_queue.cc | 3 +- + src/torrent/download/choke_queue.h | 5 +- + src/torrent/download/group_entry.h | 3 +- + src/torrent/download/resource_manager.cc | 1 - + src/torrent/download/resource_manager.h | 2 +- + src/torrent/download_info.h | 4 +- + src/torrent/error.cc | 6 +- + src/torrent/error.h | 7 +- + src/torrent/event.cc | 19 + + src/torrent/event.h | 82 ++- + src/torrent/http.h | 2 +- + src/torrent/net/Makefile.am | 18 +- + src/torrent/net/address_info.cc | 43 ++ + src/torrent/net/address_info.h | 69 +++ + src/torrent/net/fd.cc | 209 +++++++ + src/torrent/net/fd.h | 63 ++ + src/torrent/net/socket_address.cc | 559 ++++++++++++++++++ + src/torrent/net/socket_address.h | 229 +++++++ + src/torrent/net/socket_address_key.h | 2 +- + src/torrent/net/socket_event.cc | 29 + + src/torrent/net/socket_event.h | 31 + + src/torrent/net/types.h | 33 ++ + src/torrent/object.h | 21 +- + src/torrent/peer/client_list.cc | 2 +- + src/torrent/peer/connection_list.h | 3 +- + src/torrent/peer/peer_list.cc | 7 +- + src/torrent/poll.h | 3 +- + src/torrent/torrent.cc | 42 +- + src/torrent/torrent.h | 11 +- + src/torrent/tracker.h | 2 +- + src/torrent/tracker_controller.h | 3 +- + src/torrent/tracker_list.h | 2 +- + src/torrent/utils/Makefile.am | 5 +- + src/torrent/utils/directory_events.h | 3 +- + src/torrent/utils/log.cc | 66 +-- + src/torrent/utils/log.h | 98 ++- + src/torrent/utils/log_buffer.cc | 55 +- + src/torrent/utils/log_buffer.h | 52 +- + src/torrent/utils/net.cc | 72 --- + src/torrent/utils/net.h | 56 -- + src/torrent/utils/option_strings.cc | 63 +- + src/torrent/utils/option_strings.h | 7 +- + src/torrent/utils/random.cc | 29 + + src/torrent/utils/random.h | 15 + + src/torrent/utils/ranges.h | 1 - + src/torrent/utils/resume.cc | 2 - + src/torrent/utils/signal_bitfield.h | 3 +- + src/torrent/utils/thread_base.h | 3 +- + src/utils/instrumentation.cc | 2 - + src/utils/instrumentation.h | 3 +- + src/utils/queue_buckets.h | 4 +- + src/utils/sha_fast.h | 2 +- + test/Makefile.am | 29 +- + test/data/hash_check_queue_test.cc | 2 +- + test/data/hash_queue_test.cc | 2 +- + test/helpers/expect_fd.h | 107 ++++ + test/helpers/expect_utils.h | 13 + + test/helpers/mock_compare.h | 96 +++ + test/helpers/mock_function.cc | 170 ++++++ + test/helpers/mock_function.h | 133 +++++ + test/helpers/network.h | 182 ++++++ + test/helpers/progress_listener.cc | 63 ++ + test/helpers/progress_listener.h | 47 ++ + test/helpers/test_fixture.cc | 18 + + test/helpers/test_fixture.h | 14 + + test/helpers/utils.h | 60 ++ + test/main.cc | 82 ++- + test/net/test_socket_listen.cc | 398 +++++++++++++ + test/net/test_socket_listen.h | 44 ++ + test/torrent/net/test_address_info.cc | 62 ++ + test/torrent/net/test_address_info.h | 19 + + test/torrent/net/test_fd.cc | 24 + + test/torrent/net/test_fd.h | 12 + + test/torrent/net/test_socket_address.cc | 383 ++++++++++++ + test/torrent/net/test_socket_address.h | 43 ++ + test/torrent/net/test_socket_address_key.cc | 87 --- + test/torrent/object_stream_test.cc | 4 +- + test/torrent/tracker_controller_features.cc | 2 +- + test/torrent/tracker_controller_requesting.cc | 2 +- + test/torrent/tracker_controller_test.cc | 2 +- + test/torrent/tracker_list_features_test.cc | 2 +- + test/torrent/utils/directory_events_test.cc | 4 +- + test/torrent/utils/log_buffer_test.h | 17 - + test/torrent/utils/log_test.cc | 4 +- + test/torrent/utils/net_test.cc | 32 - + test/torrent/utils/net_test.h | 15 - + test/torrent/utils/option_strings_test.cc | 3 +- + test/torrent/utils/test_extents.cc | 2 +- + ...{log_buffer_test.cc => test_log_buffer.cc} | 14 +- + test/torrent/utils/test_log_buffer.h | 17 + + test/torrent/utils/test_uri_parser.cc | 2 +- + test/torrent/utils/thread_base_test.cc | 3 +- + 152 files changed, 3968 insertions(+), 1110 deletions(-) + create mode 100644 .dir-locals.el + create mode 100644 scripts/ssl.m4 + create mode 100644 src/net/socket_listen.cc + create mode 100644 src/net/socket_listen.h + create mode 100644 src/torrent/event.cc + create mode 100644 src/torrent/net/address_info.cc + create mode 100644 src/torrent/net/address_info.h + create mode 100644 src/torrent/net/fd.cc + create mode 100644 src/torrent/net/fd.h + create mode 100644 src/torrent/net/socket_address.cc + create mode 100644 src/torrent/net/socket_address.h + create mode 100644 src/torrent/net/socket_event.cc + create mode 100644 src/torrent/net/socket_event.h + create mode 100644 src/torrent/net/types.h + delete mode 100644 src/torrent/utils/net.cc + delete mode 100644 src/torrent/utils/net.h + create mode 100644 src/torrent/utils/random.cc + create mode 100644 src/torrent/utils/random.h + create mode 100644 test/helpers/expect_fd.h + create mode 100644 test/helpers/expect_utils.h + create mode 100644 test/helpers/mock_compare.h + create mode 100644 test/helpers/mock_function.cc + create mode 100644 test/helpers/mock_function.h + create mode 100644 test/helpers/network.h + create mode 100644 test/helpers/progress_listener.cc + create mode 100644 test/helpers/progress_listener.h + create mode 100644 test/helpers/test_fixture.cc + create mode 100644 test/helpers/test_fixture.h + create mode 100644 test/helpers/utils.h + create mode 100644 test/net/test_socket_listen.cc + create mode 100644 test/net/test_socket_listen.h + create mode 100644 test/torrent/net/test_address_info.cc + create mode 100644 test/torrent/net/test_address_info.h + create mode 100644 test/torrent/net/test_fd.cc + create mode 100644 test/torrent/net/test_fd.h + create mode 100644 test/torrent/net/test_socket_address.cc + create mode 100644 test/torrent/net/test_socket_address.h + delete mode 100644 test/torrent/net/test_socket_address_key.cc + delete mode 100644 test/torrent/utils/log_buffer_test.h + delete mode 100644 test/torrent/utils/net_test.cc + delete mode 100644 test/torrent/utils/net_test.h + rename test/torrent/utils/{log_buffer_test.cc => test_log_buffer.cc} (86%) + create mode 100644 test/torrent/utils/test_log_buffer.h + +diff --git a/.dir-locals.el b/.dir-locals.el +new file mode 100644 +index 00000000..af1189f2 +--- /dev/null ++++ b/.dir-locals.el +@@ -0,0 +1,7 @@ ++;;; Directory Local Variables ++;;; For more information see (info "(emacs) Directory Variables") ++ ++((c++-mode ++ (flycheck-clang-language-standard . "c++11") ++ (flycheck-gcc-language-standard . "c++11"))) ++ +diff --git a/Makefile.am b/Makefile.am +index f175e634..9507b9ea 100644 +--- a/Makefile.am ++++ b/Makefile.am +@@ -8,6 +8,7 @@ EXTRA_DIST= \ + scripts/checks.m4 \ + scripts/common.m4 \ + scripts/attributes.m4 \ ++ scripts/ssl.m4 \ + doc/main.xml \ + doc/http.xml \ + doc/torrent.xml \ +diff --git a/configure.ac b/configure.ac +index 4ed08124..620ca552 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -17,7 +17,7 @@ AC_SUBST(LIBTORRENT_CURRENT) + AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO) + AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO) + +-AM_INIT_AUTOMAKE ++AM_INIT_AUTOMAKE([serial-tests]) + AC_CONFIG_HEADERS(config.h) + + AC_PROG_CXX +@@ -35,7 +35,6 @@ RAK_ENABLE_EXTRA_DEBUG + RAK_ENABLE_WERROR + + RAK_CHECK_CXX11 +-RAK_CHECK_TR1_LIB + + AC_SYS_LARGEFILE + +@@ -67,41 +66,8 @@ CFLAGS="$PTHREAD_CFLAGS $CPPUNIT_CFLAGS $CFLAGS" + CXXFLAGS="$PTHREAD_CFLAGS $CPPUNIT_CFLAGS $CXXFLAGS" + LIBS="$PTHREAD_LIBS $CPPUNIT_LIBS $LIBS" + +-AC_ARG_ENABLE(openssl, +- [ --disable-openssl Don't use OpenSSL's SHA1 implementation.], +- [ +- if test "$enableval" = "yes"; then +-dnl move to scripts. +- PKG_CHECK_MODULES(OPENSSL, libcrypto, +- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS"; +- LIBS="$LIBS $OPENSSL_LIBS") +- +- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.) +- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.) +- AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)]) +- +- else +- AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.) +- fi +- ],[ +- PKG_CHECK_MODULES(OPENSSL, libcrypto, +- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS"; +- LIBS="$LIBS $OPENSSL_LIBS") +- +- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.) +- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.) +- AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)]) +- ] +-) +- +-AC_ARG_ENABLE(cyrus-rc4, +- [ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.], +- [ +- CXXFLAGS="$CXXFLAGS -I${enableval}/include"; +- LIBS="$LIBS -lrc4 -L${enableval}/lib" +- AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.) +- ] +-) ++TORRENT_ARG_OPENSSL ++TORRENT_ARG_CYRUS_RC4 + + AC_CHECK_FUNCS(posix_memalign) + +diff --git a/extra/corrupt_file.cc b/extra/corrupt_file.cc +index 2a818cc7..7ae906e6 100644 +--- a/extra/corrupt_file.cc ++++ b/extra/corrupt_file.cc +@@ -1,6 +1,6 @@ + #include + #include +-#include ++#include + #include + #include + #include +diff --git a/rak/file_stat.h b/rak/file_stat.h +index 5ad45e8f..f1ad8c2b 100644 +--- a/rak/file_stat.h ++++ b/rak/file_stat.h +@@ -38,7 +38,7 @@ + #define RAK_FILE_STAT_H + + #include +-#include ++#include + #include + + namespace rak { +diff --git a/rak/fs_stat.h b/rak/fs_stat.h +index 5e844277..2d73ff1b 100644 +--- a/rak/fs_stat.h ++++ b/rak/fs_stat.h +@@ -38,7 +38,7 @@ + #define RAK_FS_STAT_H + + #include +-#include ++#include + + #include + +diff --git a/rak/partial_queue.h b/rak/partial_queue.h +index 6650a633..1abfdddf 100644 +--- a/rak/partial_queue.h ++++ b/rak/partial_queue.h +@@ -39,7 +39,7 @@ + + #include + #include +-#include ++#include + + namespace rak { + +diff --git a/rak/path.h b/rak/path.h +index bfe8ccc1..64daf355 100644 +--- a/rak/path.h ++++ b/rak/path.h +@@ -99,7 +99,7 @@ path_expand(const char* src, char* first, char* last) { + src++; + } + +- return std::max(first + strlcpy(first, src, std::distance(first, last)), last); ++ return std::min(first + strlcpy(first, src, std::distance(first, last)), last); + } + + } +diff --git a/rak/priority_queue_default.h b/rak/priority_queue_default.h +index 01a0070e..a7bba0ce 100644 +--- a/rak/priority_queue_default.h ++++ b/rak/priority_queue_default.h +@@ -37,7 +37,7 @@ + #ifndef RAK_PRIORITY_QUEUE_DEFAULT_H + #define RAK_PRIORITY_QUEUE_DEFAULT_H + +-#include lt_tr1_functional ++#include + #include + #include + #include +diff --git a/rak/socket_address.h b/rak/socket_address.h +index 961c53b2..8eb60116 100644 +--- a/rak/socket_address.h ++++ b/rak/socket_address.h +@@ -47,9 +47,12 @@ + #ifndef RAK_SOCKET_ADDRESS_H + #define RAK_SOCKET_ADDRESS_H + ++#include ++#include + #include +-#include + #include ++#include ++ + #include + #include + #include +@@ -84,7 +87,6 @@ public: + + bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; } + +- // Should we need to set AF_UNSPEC? + void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); } + + sa_family_t family() const { return m_sockaddr.sa_family; } +@@ -124,6 +126,7 @@ public: + // extranous bytes and ensure it does not go beyond the size of this + // struct. + void copy(const socket_address& src, size_t length); ++ void copy_sockaddr(const sockaddr* src); + + static socket_address* cast_from(sockaddr* sa) { return reinterpret_cast(sa); } + static const socket_address* cast_from(const sockaddr* sa) { return reinterpret_cast(sa); } +@@ -220,6 +223,8 @@ public: + + void set_address_any() { set_port(0); set_address(in6addr_any); } + ++ std::string pretty_address_str() const; ++ + sa_family_t family() const { return m_sockaddr.sin6_family; } + void set_family() { m_sockaddr.sin6_family = AF_INET6; } + +@@ -340,7 +345,7 @@ socket_address::pretty_address_str() const { + case af_inet: + return sa_inet()->address_str(); + case af_inet6: +- return sa_inet6()->address_str(); ++ return sa_inet6()->pretty_address_str(); + case af_unspec: + return std::string("unspec"); + default: +@@ -380,13 +385,16 @@ socket_address::length() const { + inline void + socket_address::copy(const socket_address& src, size_t length) { + length = std::min(length, sizeof(socket_address)); +- +- // Does this get properly optimized? ++ + std::memset(this, 0, sizeof(socket_address)); + std::memcpy(this, &src, length); + } + +-// Should we be able to compare af_unspec? ++inline void ++socket_address::copy_sockaddr(const sockaddr* src) { ++ std::memset(this, 0, sizeof(socket_address)); ++ std::memcpy(this, src, socket_address::cast_from(src)->length()); ++} + + inline bool + socket_address::operator == (const socket_address& rhs) const { +@@ -488,6 +496,35 @@ socket_address_inet6::set_address_c_str(const char* a) { + return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr); + } + ++inline std::string ++socket_address_inet6::pretty_address_str() const { ++ char buf[INET6_ADDRSTRLEN + 2 + 6]; ++ ++ if (inet_ntop(family(), &m_sockaddr.sin6_addr, buf + 1, INET6_ADDRSTRLEN) == NULL) ++ return std::string(); ++ ++ buf[0] = '['; ++ ++ char* last_char = (char*)std::memchr(buf + 1, 0, INET6_ADDRSTRLEN); ++ ++ // TODO: Throw exception here. ++ ++ if (last_char == NULL || last_char >= buf + 1 + INET6_ADDRSTRLEN) ++ throw std::logic_error("inet_ntop for inet6 returned bad buffer"); ++ ++ *(last_char++) = ']'; ++ ++ if (!is_port_any()) { ++ if (snprintf(last_char, 7, ":%" PRIu16, port()) == -1) ++ return std::string("error"); // TODO: Throw here. ++ ++ } else { ++ *last_char = '\0'; ++ } ++ ++ return std::string(buf); ++} ++ + inline socket_address + socket_address_inet6::normalize_address() const { + const uint32_t *addr32 = reinterpret_cast(m_sockaddr.sin6_addr.s6_addr); +diff --git a/rak/timer.h b/rak/timer.h +index e25ad2e6..842a2e53 100644 +--- a/rak/timer.h ++++ b/rak/timer.h +@@ -38,7 +38,7 @@ + #define RAK_TIMER_H + + #include +-#include ++#include + #include + + namespace rak { +diff --git a/scripts/checks.m4 b/scripts/checks.m4 +index 83be8461..98ef17f8 100644 +--- a/scripts/checks.m4 ++++ b/scripts/checks.m4 +@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [ + [ + AC_DEFINE(USE_KQUEUE, 1, Use kqueue.) + AC_MSG_RESULT(yes) ++ TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ], [ + AC_MSG_RESULT(no) + ]) +@@ -137,7 +138,6 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [ + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ]) + ]) +@@ -149,11 +149,9 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + fi + ], [ + TORRENT_CHECK_KQUEUE +- TORRENT_CHECK_KQUEUE_SOCKET_ONLY + ]) + ]) + +diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4 +index 3660f3a7..0db61b83 100644 +--- a/scripts/rak_cxx.m4 ++++ b/scripts/rak_cxx.m4 +@@ -12,50 +12,3 @@ AC_DEFUN([RAK_CHECK_CXX11], [ + ] + ) + ]) +- +-AC_DEFUN([RAK_CHECK_TR1_LIB], [ +- AC_LANG_PUSH(C++) +- AC_MSG_CHECKING(should use TR1 headers) +- +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +- #include +- class Foo; typedef std::unordered_map Bar; +- Bar b1; +- ]) +- ], [ +- AC_MSG_RESULT(no) +- AC_DEFINE(USE_TR1_LIB, 0, Define to 1 if you need to use TR1 containers.) +- +- AC_DEFINE([lt_tr1_array], [], [TR1 array]) +- AC_DEFINE([lt_tr1_functional], [], [TR1 functional]) +- AC_DEFINE([lt_tr1_memory], [], [TR1 memory]) +- AC_DEFINE([lt_tr1_unordered_map], [], [TR1 unordered_map]) +- +- ], [ +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +- #include +- class Foo; typedef std::tr1::unordered_map Bar; +- Bar b1; +- ]) +- ], [ +- AC_MSG_RESULT([yes]) +- AC_DEFINE(USE_TR1_LIB, 1, Define to 1 if you need to use TR1 containers.) +- +- AC_DEFINE([lt_tr1_array], [], [TR1 array]) +- AC_DEFINE([lt_tr1_functional], [], [TR1 functional]) +- AC_DEFINE([lt_tr1_memory], [], [TR1 memory]) +- AC_DEFINE([lt_tr1_unordered_map], [], [TR1 unordered_map]) +- +- ], [ +- AC_MSG_ERROR([No support for C++11 standard library nor TR1 extensions found.]) +- ]) +- ]) +- +- AH_VERBATIM(lt_tr1_zzz, [ +-#if USE_TR1_LIB == 1 +-namespace std { namespace tr1 {} using namespace tr1; } +-#endif +-]) +- +- AC_LANG_POP(C++) +-]) +diff --git a/scripts/ssl.m4 b/scripts/ssl.m4 +new file mode 100644 +index 00000000..f07349a1 +--- /dev/null ++++ b/scripts/ssl.m4 +@@ -0,0 +1,38 @@ ++AC_DEFUN([TORRENT_CHECK_OPENSSL], ++ [ ++ PKG_CHECK_MODULES(OPENSSL, libcrypto, ++ CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS"; ++ LIBS="$LIBS $OPENSSL_LIBS") ++ ++ AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.) ++ AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.) ++ ] ++) ++ ++AC_DEFUN([TORRENT_ARG_OPENSSL], ++ [ ++ AC_ARG_ENABLE(openssl, ++ [ --disable-openssl Don't use OpenSSL's SHA1 implementation.], ++ [ ++ if test "$enableval" = "yes"; then ++ TORRENT_CHECK_OPENSSL ++ else ++ AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.) ++ fi ++ ],[ ++ TORRENT_CHECK_OPENSSL ++ ]) ++ ] ++) ++ ++AC_DEFUN([TORRENT_ARG_CYRUS_RC4], ++ [ ++ AC_ARG_ENABLE(cyrus-rc4, ++ [ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.], ++ [ ++ CXXFLAGS="$CXXFLAGS -I${enableval}/include"; ++ LIBS="$LIBS -lrc4 -L${enableval}/lib" ++ AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.) ++ ]) ++ ] ++) +diff --git a/src/data/chunk_list.cc b/src/data/chunk_list.cc +index 00abbc2a..7622b825 100644 +--- a/src/data/chunk_list.cc ++++ b/src/data/chunk_list.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include + #include + +diff --git a/src/data/chunk_list.h b/src/data/chunk_list.h +index b6ff4cdb..4b40dc42 100644 +--- a/src/data/chunk_list.h ++++ b/src/data/chunk_list.h +@@ -37,9 +37,9 @@ + #ifndef LIBTORRENT_DATA_CHUNK_LIST_H + #define LIBTORRENT_DATA_CHUNK_LIST_H + ++#include + #include + #include +-#include lt_tr1_functional + + #include "chunk.h" + #include "chunk_handle.h" +diff --git a/src/data/chunk_list_node.h b/src/data/chunk_list_node.h +index 76de6671..95e4ed4f 100644 +--- a/src/data/chunk_list_node.h ++++ b/src/data/chunk_list_node.h +@@ -37,7 +37,7 @@ + #ifndef LIBTORRENT_DATA_CHUNK_LIST_NODE_H + #define LIBTORRENT_DATA_CHUNK_LIST_NODE_H + +-#include ++#include + #include + + namespace torrent { +diff --git a/src/data/hash_check_queue.h b/src/data/hash_check_queue.h +index b933f137..9f28c118 100644 +--- a/src/data/hash_check_queue.h ++++ b/src/data/hash_check_queue.h +@@ -38,8 +38,8 @@ + #define LIBTORRENT_DATA_HASH_CHECK_QUEUE_H + + #include ++#include + #include +-#include lt_tr1_functional + + #include "rak/allocators.h" + +diff --git a/src/data/hash_queue.cc b/src/data/hash_queue.cc +index 7dffaee4..3f54892b 100644 +--- a/src/data/hash_queue.cc ++++ b/src/data/hash_queue.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include + #include + #include +diff --git a/src/data/hash_queue.h b/src/data/hash_queue.h +index 6885a383..3a841967 100644 +--- a/src/data/hash_queue.h ++++ b/src/data/hash_queue.h +@@ -38,9 +38,9 @@ + #define LIBTORRENT_DATA_HASH_QUEUE_H + + #include ++#include + #include + #include +-#include lt_tr1_functional + + #include "torrent/hash_string.h" + #include "hash_queue_node.h" +diff --git a/src/data/hash_queue_node.h b/src/data/hash_queue_node.h +index aa59a062..c8367b7c 100644 +--- a/src/data/hash_queue_node.h ++++ b/src/data/hash_queue_node.h +@@ -37,9 +37,9 @@ + #ifndef LIBTORRENT_DATA_HASH_QUEUE_NODE_H + #define LIBTORRENT_DATA_HASH_QUEUE_NODE_H + ++#include ++#include + #include +-#include lt_tr1_functional +-#include + + #include "chunk_handle.h" + #include "hash_chunk.h" +diff --git a/src/data/hash_torrent.cc b/src/data/hash_torrent.cc +index 758a10fa..e803f1cb 100644 +--- a/src/data/hash_torrent.cc ++++ b/src/data/hash_torrent.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include "data/chunk_list.h" + #include "torrent/exceptions.h" + #include "torrent/data/download_data.h" +diff --git a/src/data/hash_torrent.h b/src/data/hash_torrent.h +index 6af643f2..9ce2f100 100644 +--- a/src/data/hash_torrent.h ++++ b/src/data/hash_torrent.h +@@ -37,9 +37,9 @@ + #ifndef LIBTORRENT_DATA_HASH_TORRENT_H + #define LIBTORRENT_DATA_HASH_TORRENT_H + ++#include ++#include + #include +-#include +-#include lt_tr1_functional + #include + + #include "data/chunk_handle.h" +diff --git a/src/data/memory_chunk.h b/src/data/memory_chunk.h +index cc32eff1..d2b5565d 100644 +--- a/src/data/memory_chunk.h ++++ b/src/data/memory_chunk.h +@@ -38,7 +38,7 @@ + #define LIBTORRENT_DATA_MEMORY_CHUNK_H + + #include +-#include ++#include + #include + #include + +diff --git a/src/data/socket_file.h b/src/data/socket_file.h +index 7b27af8c..d25c4a44 100644 +--- a/src/data/socket_file.h ++++ b/src/data/socket_file.h +@@ -38,7 +38,7 @@ + #define LIBTORRENT_SOCKET_FILE_H + + #include +-#include ++#include + #include + #include + +diff --git a/src/dht/dht_hash_map.h b/src/dht/dht_hash_map.h +index 140f070b..1506db56 100644 +--- a/src/dht/dht_hash_map.h ++++ b/src/dht/dht_hash_map.h +@@ -39,20 +39,14 @@ + + #include "config.h" + +-#if HAVE_TR1 +-#include +-#else +-#include +-#endif +- +-#include "torrent/hash_string.h" ++#include + + #include "dht_node.h" + #include "dht_tracker.h" ++#include "torrent/hash_string.h" + + namespace torrent { + +-#if HAVE_TR1 + // Hash functions for HashString keys, and dereferencing HashString pointers. + + // Since the first few bits are very similar if not identical (since the IDs +@@ -142,53 +136,6 @@ public: + + }; + +-#else +- +-// Compare HashString pointers by dereferencing them. +-struct hashstring_ptr_less : public std::binary_function { +- size_t operator () (const HashString* one, const HashString* two) const +- { return *one < *two; } +-}; +- +-class DhtNodeList : public std::map { +-public: +- typedef std::map base_type; +- +- // Define accessor iterator with more convenient access to the key and +- // element values. Allows changing the map definition more easily if needed. +- template +- struct accessor_wrapper : public T { +- accessor_wrapper(const T& itr) : T(itr) { } +- +- const HashString& id() const { return *(**this).first; } +- DhtNode* node() const { return (**this).second; } +- }; +- +- typedef accessor_wrapper const_accessor; +- typedef accessor_wrapper accessor; +- +- DhtNode* add_node(DhtNode* n); +- +-}; +- +-class DhtTrackerList : public std::map { +-public: +- typedef std::map base_type; +- +- template +- struct accessor_wrapper : public T { +- accessor_wrapper(const T& itr) : T(itr) { } +- +- const HashString& id() const { return (**this).first; } +- DhtTracker* tracker() const { return (**this).second; } +- }; +- +- typedef accessor_wrapper const_accessor; +- typedef accessor_wrapper accessor; +- +-}; +-#endif // HAVE_TR1 +- + inline + DhtNode* DhtNodeList::add_node(DhtNode* n) { + insert(std::make_pair((const HashString*)n, (DhtNode*)n)); +diff --git a/src/download/chunk_selector.h b/src/download/chunk_selector.h +index 52c31fd5..ab1b8c17 100644 +--- a/src/download/chunk_selector.h ++++ b/src/download/chunk_selector.h +@@ -37,7 +37,7 @@ + #ifndef LIBTORRENT_DOWNLOAD_CHUNK_SELECTOR_H + #define LIBTORRENT_DOWNLOAD_CHUNK_SELECTOR_H + +-#include ++#include + #include + + #include "torrent/bitfield.h" +diff --git a/src/download/chunk_statistics.h b/src/download/chunk_statistics.h +index 816ec6c9..62f76c5a 100644 +--- a/src/download/chunk_statistics.h ++++ b/src/download/chunk_statistics.h +@@ -37,7 +37,7 @@ + #ifndef LIBTORRENT_DOWNLOAD_CHUNK_STATISTICS_H + #define LIBTORRENT_DOWNLOAD_CHUNK_STATISTICS_H + +-#include ++#include + #include + + namespace torrent { +diff --git a/src/download/delegator.cc b/src/download/delegator.cc +index 711cd461..27ae42ec 100644 +--- a/src/download/delegator.cc ++++ b/src/download/delegator.cc +@@ -39,7 +39,7 @@ + #include "config.h" + + #include +-#include ++#include + + #include "torrent/exceptions.h" + #include "torrent/bitfield.h" +diff --git a/src/download/delegator.h b/src/download/delegator.h +index 3b997b81..b75d4c2a 100644 +--- a/src/download/delegator.h ++++ b/src/download/delegator.h +@@ -37,9 +37,9 @@ + #ifndef LIBTORRENT_DELEGATOR_H + #define LIBTORRENT_DELEGATOR_H + ++#include + #include + #include +-#include lt_tr1_functional + + #include "torrent/data/transfer_list.h" + +diff --git a/src/download/download_constructor.h b/src/download/download_constructor.h +index 7d43aba3..6a09b7f1 100644 +--- a/src/download/download_constructor.h ++++ b/src/download/download_constructor.h +@@ -39,7 +39,7 @@ + + #include + #include +-#include ++#include + + namespace torrent { + +diff --git a/src/globals.cc b/src/globals.cc +index 88130c19..20644fbd 100644 +--- a/src/globals.cc ++++ b/src/globals.cc +@@ -37,11 +37,24 @@ + #include "config.h" + + #include "globals.h" +-#include "torrent/common.h" ++#include "manager.h" ++#include "torrent/connection_manager.h" ++#include "torrent/event.h" ++#include "torrent/poll.h" + + namespace torrent { + + LIBTORRENT_EXPORT rak::priority_queue_default taskScheduler; + LIBTORRENT_EXPORT rak::timer cachedTime; + ++void poll_event_open(Event* event) { manager->poll()->open(event); manager->connection_manager()->inc_socket_count(); } ++void poll_event_close(Event* event) { manager->poll()->close(event); manager->connection_manager()->dec_socket_count(); } ++void poll_event_closed(Event* event) { manager->poll()->closed(event); manager->connection_manager()->dec_socket_count(); } ++void poll_event_insert_read(Event* event) { manager->poll()->insert_read(event); } ++void poll_event_insert_write(Event* event) { manager->poll()->insert_write(event); } ++void poll_event_insert_error(Event* event) { manager->poll()->insert_error(event); } ++void poll_event_remove_read(Event* event) { manager->poll()->remove_read(event); } ++void poll_event_remove_write(Event* event) { manager->poll()->remove_write(event); } ++void poll_event_remove_error(Event* event) { manager->poll()->remove_error(event); } ++ + } +diff --git a/src/globals.h b/src/globals.h +index 564ac86d..e9fe1177 100644 +--- a/src/globals.h ++++ b/src/globals.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_GLOBALS_H + #define LIBTORRENT_GLOBALS_H + +diff --git a/src/manager.cc b/src/manager.cc +index c503974d..11ef4b0f 100644 +--- a/src/manager.cc ++++ b/src/manager.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include "torrent/exceptions.h" +diff --git a/src/net/Makefile.am b/src/net/Makefile.am +index fb4da4f3..e3a8c7e1 100644 +--- a/src/net/Makefile.am ++++ b/src/net/Makefile.am +@@ -15,6 +15,8 @@ libsub_net_la_SOURCES = \ + socket_datagram.h \ + socket_fd.cc \ + socket_fd.h \ ++ socket_listen.cc \ ++ socket_listen.h \ + socket_set.cc \ + socket_set.h \ + socket_stream.cc \ +diff --git a/src/net/data_buffer.h b/src/net/data_buffer.h +index d35cdc48..5dd0cb30 100644 +--- a/src/net/data_buffer.h ++++ b/src/net/data_buffer.h +@@ -38,7 +38,7 @@ + #define LIBTORRENT_NET_DATA_BUFFER_H + + #include +-#include ++#include + + namespace torrent { + +diff --git a/src/net/listen.cc b/src/net/listen.cc +index d424e94c..61fedbf8 100644 +--- a/src/net/listen.cc ++++ b/src/net/listen.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #define __STDC_FORMAT_MACROS +@@ -95,7 +59,7 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre + manager->poll()->insert_read(this); + manager->poll()->insert_error(this); + +- lt_log_print(LOG_CONNECTION_INFO, "listen port %" PRIu16 " opened with backlog set to %i", ++ lt_log_print(LOG_CONNECTION_LISTEN, "listen port %" PRIu16 " opened with backlog set to %i", + m_port, backlog); + + return true; +@@ -107,7 +71,7 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre + get_fd().close(); + get_fd().clear(); + +- lt_log_print(LOG_CONNECTION_INFO, "failed to open listen port"); ++ lt_log_print(LOG_CONNECTION_LISTEN, "failed to open listen port"); + + return false; + } +diff --git a/src/net/listen.h b/src/net/listen.h +index b3c845aa..58c06c7e 100644 +--- a/src/net/listen.h ++++ b/src/net/listen.h +@@ -37,8 +37,8 @@ + #ifndef LIBTORRENT_LISTEN_H + #define LIBTORRENT_LISTEN_H + +-#include +-#include lt_tr1_functional ++#include ++#include + #include + + #include "socket_base.h" +diff --git a/src/net/protocol_buffer.h b/src/net/protocol_buffer.h +index b64d47ea..f9711ded 100644 +--- a/src/net/protocol_buffer.h ++++ b/src/net/protocol_buffer.h +@@ -38,7 +38,7 @@ + #define LIBTORRENT_NET_PROTOCOL_BUFFER_H + + #include +-#include ++#include + #include + + #include "torrent/exceptions.h" +diff --git a/src/net/socket_base.h b/src/net/socket_base.h +index 02c9497d..20ae1d9f 100644 +--- a/src/net/socket_base.h ++++ b/src/net/socket_base.h +@@ -38,7 +38,7 @@ + #define LIBTORRENT_NET_SOCKET_BASE_H + + #include +-#include ++#include + + #include "torrent/event.h" + #include "socket_fd.h" +diff --git a/src/net/socket_fd.cc b/src/net/socket_fd.cc +index f04059f6..c36ff4b9 100644 +--- a/src/net/socket_fd.cc ++++ b/src/net/socket_fd.cc +@@ -210,6 +210,11 @@ SocketFd::bind(const rak::socket_address& sa, unsigned int length) { + return !::bind(m_fd, sa.c_sockaddr(), length); + } + ++bool ++SocketFd::bind_sa(const sockaddr* sa) { ++ return bind(*rak::socket_address::cast_from(sa)); ++} ++ + bool + SocketFd::connect(const rak::socket_address& sa) { + check_valid(); +@@ -222,6 +227,11 @@ SocketFd::connect(const rak::socket_address& sa) { + return !::connect(m_fd, sa.c_sockaddr(), sa.length()) || errno == EINPROGRESS; + } + ++bool ++SocketFd::connect_sa(const sockaddr* sa) { ++ return connect(*rak::socket_address::cast_from(sa)); ++} ++ + bool + SocketFd::getsockname(rak::socket_address *sa) { + check_valid(); +diff --git a/src/net/socket_fd.h b/src/net/socket_fd.h +index 2329b4e9..4db0087b 100644 +--- a/src/net/socket_fd.h ++++ b/src/net/socket_fd.h +@@ -39,6 +39,8 @@ + + #include + ++struct sockaddr; ++ + namespace rak { + class socket_address; + } +@@ -80,7 +82,11 @@ public: + + bool bind(const rak::socket_address& sa); + bool bind(const rak::socket_address& sa, unsigned int length); ++ bool bind_sa(const sockaddr* sa); ++ + bool connect(const rak::socket_address& sa); ++ bool connect_sa(const sockaddr* sa); ++ + bool getsockname(rak::socket_address* sa); + + bool listen(int size); +diff --git a/src/net/socket_listen.cc b/src/net/socket_listen.cc +new file mode 100644 +index 00000000..97f006e0 +--- /dev/null ++++ b/src/net/socket_listen.cc +@@ -0,0 +1,137 @@ ++#include "config.h" ++ ++#include "socket_listen.h" ++ ++#include ++ ++#include "torrent/connection_manager.h" ++#include "torrent/exceptions.h" ++#include "torrent/utils/log.h" ++#include "torrent/utils/random.h" ++ ++#define LT_LOG_SAP(log_fmt, sap, ...) \ ++ lt_log_print(LOG_CONNECTION_LISTEN, "listen->%s: " log_fmt, sap_pretty_str(sap).c_str(), __VA_ARGS__); ++ ++namespace torrent { ++ ++socket_listen::socket_listen() : m_backlog(SOMAXCONN) { ++} ++ ++void ++socket_listen::set_backlog(int backlog) { ++ if (backlog < 0 || backlog > SOMAXCONN) ++ throw internal_error("Could not set socket_listen backlog, out-of-range value."); ++ ++ m_backlog = backlog; ++} ++ ++bool ++socket_listen::open(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, uint16_t start_port, fd_flags open_flags) { ++ if (is_open()) ++ throw internal_error("socket_listen::open: already open"); ++ ++ if (!(sap_is_inet(sap) || sap_is_inet6(sap)) || sap_is_v4mapped(sap) || !sap_is_port_any(sap) || sap_is_broadcast(sap)) ++ throw internal_error("socket_listen::open: socket address must be inet/inet6 with no port, and not v4mapped nor broadcast: " + sap_pretty_str(sap)); ++ ++ if (sap_is_inet(sap) && !(open_flags & fd_flag_v4only)) ++ throw internal_error("socket_listen::open: socket address is inet without v4only flag"); ++ ++ if (first_port == 0 || last_port == 0 || start_port == 0 || ++ !(first_port <= last_port && first_port <= start_port && start_port <= last_port)) ++ throw internal_error("socket_listen::open: port range not valid"); ++ ++ int fd = fd_open(open_flags); ++ ++ if (fd == -1) { ++ LT_LOG_SAP("open failed (flags:0x%x errno:%i message:'%s')", sap, open_flags, errno, std::strerror(errno)); ++ return false; ++ } ++ ++ uint16_t p = start_port; ++ ++ do { ++ if (m_open_port(fd, sap, p)) ++ return is_open(); ++ ++ if (p == last_port) ++ p = first_port; ++ else ++ p++; ++ } while (p != start_port); ++ ++ LT_LOG_SAP("listen ports exhausted (fd:%i first_port:%" PRIu16 " last_port:%" PRIu16 ")", ++ sap, fd, first_port, last_port); ++ fd_close(fd); ++ return false; ++} ++ ++bool ++socket_listen::open_randomize(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags) { ++ if (last_port < first_port) ++ throw internal_error("socket_listen::open_randomize: port range not valid"); ++ ++ return open(std::move(sap), first_port, last_port, random_uniform_uint16(first_port, last_port), open_flags); ++} ++ ++bool ++socket_listen::open_sequential(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags) { ++ return open(std::move(sap), first_port, last_port, first_port, open_flags); ++} ++ ++void ++socket_listen::close() { ++ if (!is_open()) ++ return; ++ ++ torrent::poll_event_closed(this); ++ ++ fd_close(file_descriptor()); ++ set_file_descriptor(-1); ++ m_socket_address.reset(); ++} ++ ++void ++socket_listen::event_read() { ++} ++ ++void ++socket_listen::event_error() { ++} ++ ++// Returns true if open is successful or if we cannot bind to the ++// address, returns false if other ports can be used. ++bool ++socket_listen::m_open_port(int fd, sa_unique_ptr& sap, uint16_t port) { ++ sap_set_port(sap, port); ++ ++ if (!fd_bind(fd, sap.get())) { ++ if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) { ++ LT_LOG_SAP("listen address not usable (fd:%i errno:%i message:'%s')", ++ sap, fd, errno, std::strerror(errno)); ++ fd_close(fd); ++ return true; ++ } ++ ++ return false; ++ } ++ ++ if (!fd_listen(fd, m_backlog)) { ++ LT_LOG_SAP("call to listen failed (fd:%i backlog:%i errno:%i message:'%s')", ++ sap, fd, m_backlog, errno, std::strerror(errno)); ++ fd_close(fd); ++ return true; ++ } ++ ++ LT_LOG_SAP("open listen port success (fd:%i backlog:%i)", sap, fd, m_backlog); ++ ++ m_fileDesc = fd; ++ m_socket_address.swap(sap); ++ ++ torrent::poll_event_open(this); ++ torrent::poll_event_insert_read(this); ++ torrent::poll_event_insert_error(this); ++ ++ return true; ++} ++ ++} +diff --git a/src/net/socket_listen.h b/src/net/socket_listen.h +new file mode 100644 +index 00000000..817d5fa5 +--- /dev/null ++++ b/src/net/socket_listen.h +@@ -0,0 +1,46 @@ ++#ifndef LIBTORRENT_SOCKET_LISTEN_H ++#define LIBTORRENT_SOCKET_LISTEN_H ++ ++#include ++#include ++ ++#include "torrent/net/fd.h" ++#include "torrent/net/socket_address.h" ++#include "torrent/net/socket_event.h" ++ ++namespace torrent { ++ ++class socket_listen : public socket_event { ++public: ++ typedef std::function accepted_ftor; ++ ++ socket_listen(); ++ ++ int backlog() const; ++ ++ void set_backlog(int backlog); ++ void set_slot_accepted(accepted_ftor&& ftor); ++ ++ bool open(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, uint16_t start_port, fd_flags open_flags); ++ bool open_randomize(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags); ++ bool open_sequential(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags); ++ void close(); ++ ++ void event_read() override; ++ void event_error() override; ++ ++ const char* type_name() const override { return "socket_listen"; } ++ ++private: ++ bool m_open_port(int fd, sa_unique_ptr& sap, uint16_t port); ++ ++ int m_backlog; ++ accepted_ftor m_slot_accepted; ++}; ++ ++inline int socket_listen::backlog() const { return m_backlog; } ++inline void socket_listen::set_slot_accepted(accepted_ftor&& ftor) { m_slot_accepted = ftor; } ++ ++} ++ ++#endif +diff --git a/src/net/socket_set.h b/src/net/socket_set.h +index 9264edf7..78443c88 100644 +--- a/src/net/socket_set.h ++++ b/src/net/socket_set.h +@@ -39,7 +39,7 @@ + + #include + #include +-#include ++#include + #include + + #include "torrent/exceptions.h" +diff --git a/src/net/throttle_node.h b/src/net/throttle_node.h +index 77cb6cc7..5af27a22 100644 +--- a/src/net/throttle_node.h ++++ b/src/net/throttle_node.h +@@ -37,7 +37,7 @@ + #ifndef LIBTORRENT_NET_THROTTLE_NODE_H + #define LIBTORRENT_NET_THROTTLE_NODE_H + +-#include lt_tr1_functional ++#include + + #include "torrent/rate.h" + +diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc +index 6b41bbe3..1b877c7a 100644 +--- a/src/protocol/handshake.cc ++++ b/src/protocol/handshake.cc +@@ -46,6 +46,7 @@ + #include "torrent/error.h" + #include "torrent/poll.h" + #include "torrent/throttle.h" ++#include "torrent/utils/log.h" + #include "utils/diffie_hellman.h" + + #include "globals.h" +@@ -55,6 +56,10 @@ + #include "handshake.h" + #include "handshake_manager.h" + ++#define LT_LOG(log_fmt, ...) \ ++ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake->%s: " log_fmt, \ ++ m_address.pretty_address_str().c_str(), __VA_ARGS__); ++ + namespace torrent { + + const char* Handshake::m_protocol = "BitTorrent protocol"; +@@ -862,7 +867,7 @@ restart: + m_manager->receive_failed(this, e.type(), e.error()); + + } catch (network_error& e) { +- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error); ++ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_read_error); + } + } + +@@ -969,7 +974,7 @@ Handshake::event_write() { + m_manager->receive_failed(this, e.type(), e.error()); + + } catch (network_error& e) { +- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error); ++ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_write_error); + } + } + +@@ -1070,7 +1075,7 @@ Handshake::prepare_peer_info() { + m_peerInfo = m_download->peer_list()->connected(m_address.c_sockaddr(), PeerList::connect_incoming); + + if (m_peerInfo == NULL) +- throw handshake_error(ConnectionManager::handshake_failed, e_handshake_network_error); ++ throw handshake_error(ConnectionManager::handshake_failed, e_handshake_no_peer_info); + + if (m_peerInfo->failed_counter() > m_manager->max_failed) + throw handshake_error(ConnectionManager::handshake_dropped, e_handshake_toomanyfailed); +@@ -1221,7 +1226,7 @@ Handshake::event_error() { + if (m_state == INACTIVE) + throw internal_error("Handshake::event_error() called on an inactive handshake."); + +- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error); ++ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_socket_error); + } + + } +diff --git a/src/protocol/handshake_manager.cc b/src/protocol/handshake_manager.cc +index b52c8d4e..99592ba8 100644 +--- a/src/protocol/handshake_manager.cc ++++ b/src/protocol/handshake_manager.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -54,10 +18,10 @@ + + #include "manager.h" + +-#define LT_LOG_SA(log_level, sa, log_fmt, ...) \ +- lt_log_print(LOG_CONNECTION_##log_level, "handshake_manager->%s: " log_fmt, (sa)->address_str().c_str(), __VA_ARGS__); +-#define LT_LOG_SA_C(log_level, sa, log_fmt, ...) \ +- lt_log_print(LOG_CONNECTION_##log_level, "handshake_manager->%s: " log_fmt, \ ++#define LT_LOG_SA(sa, log_fmt, ...) \ ++ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake_manager->%s: " log_fmt, (sa)->address_str().c_str(), __VA_ARGS__); ++#define LT_LOG_SA_C(sa, log_fmt, ...) \ ++ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake_manager->%s: " log_fmt, \ + reinterpret_cast(sa)->address_str().c_str(), __VA_ARGS__); + + namespace torrent { +@@ -122,7 +86,7 @@ HandshakeManager::add_incoming(SocketFd fd, const rak::socket_address& sa) { + return; + } + +- LT_LOG_SA(INFO, &sa, "Adding incoming connection: fd:%i.", fd.get_fd()); ++ LT_LOG_SA(&sa, "Adding incoming connection: fd:%i.", fd.get_fd()); + + manager->connection_manager()->inc_socket_count(); + +@@ -183,7 +147,7 @@ HandshakeManager::create_outgoing(const rak::socket_address& sa, DownloadMain* d + else + message = ConnectionManager::handshake_outgoing; + +- LT_LOG_SA(INFO, &sa, "Adding outcoming connection: encryption:%x message:%x.", encryptionOptions, message); ++ LT_LOG_SA(&sa, "Adding outcoming connection: encryption:%x message:%x.", encryptionOptions, message); + manager->connection_manager()->inc_socket_count(); + + Handshake* handshake = new Handshake(fd, this, encryptionOptions); +@@ -213,7 +177,7 @@ HandshakeManager::receive_succeeded(Handshake* handshake) { + handshake->extensions())) != NULL) { + + manager->client_list()->retrieve_id(&handshake->peer_info()->mutable_client_info(), handshake->peer_info()->id()); +- LT_LOG_SA_C(INFO, handshake->peer_info()->socket_address(), "Handshake success.", 0); ++ LT_LOG_SA_C(handshake->peer_info()->socket_address(), "Handshake success.", 0); + + pcb->peer_chunks()->set_have_timer(handshake->initialized_time()); + +@@ -237,7 +201,7 @@ HandshakeManager::receive_succeeded(Handshake* handshake) { + else + reason = e_handshake_duplicate; + +- LT_LOG_SA_C(INFO, handshake->peer_info()->socket_address(), "Handshake dropped: %s.", strerror(reason)); ++ LT_LOG_SA_C(handshake->peer_info()->socket_address(), "Handshake dropped: %s.", strerror(reason)); + handshake->destroy_connection(); + } + +@@ -255,13 +219,13 @@ HandshakeManager::receive_failed(Handshake* handshake, int message, int error) { + handshake->deactivate_connection(); + handshake->destroy_connection(); + +- LT_LOG_SA(INFO, sa, "Received error: message:%x %s.", message, strerror(error)); ++ LT_LOG_SA(sa, "Received error: message:%x %s.", message, strerror(error)); + + if (handshake->encryption()->should_retry()) { + int retry_options = handshake->retry_options() | ConnectionManager::encryption_retrying; + DownloadMain* download = handshake->download(); + +- LT_LOG_SA(INFO, sa, "Retrying %s.", ++ LT_LOG_SA(sa, "Retrying %s.", + retry_options & ConnectionManager::encryption_try_outgoing ? "encrypted" : "plaintext"); + + create_outgoing(*sa, download, retry_options); +diff --git a/src/protocol/handshake_manager.h b/src/protocol/handshake_manager.h +index cfd52aa0..dc398e3e 100644 +--- a/src/protocol/handshake_manager.h ++++ b/src/protocol/handshake_manager.h +@@ -1,45 +1,9 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_NET_HANDSHAKE_MANAGER_H + #define LIBTORRENT_NET_HANDSHAKE_MANAGER_H + +-#include ++#include + #include +-#include lt_tr1_functional ++#include + #include + #include + #include +diff --git a/src/protocol/peer_connection_base.cc b/src/protocol/peer_connection_base.cc +index c02998fb..bd870425 100644 +--- a/src/protocol/peer_connection_base.cc ++++ b/src/protocol/peer_connection_base.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include + #include + #include +diff --git a/src/protocol/request_list.cc b/src/protocol/request_list.cc +index a4338bcb..ea5d388a 100644 +--- a/src/protocol/request_list.cc ++++ b/src/protocol/request_list.cc +@@ -1,44 +1,8 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include + #include +-#include ++#include + #include + + #include "torrent/data/block.h" +diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am +index 1bdfde3d..8cd26ce7 100644 +--- a/src/torrent/Makefile.am ++++ b/src/torrent/Makefile.am +@@ -22,6 +22,7 @@ libsub_torrent_la_SOURCES = \ + download_info.h \ + error.cc \ + error.h \ ++ event.cc \ + event.h \ + exceptions.cc \ + exceptions.h \ +diff --git a/src/torrent/common.h b/src/torrent/common.h +index 3363143d..42cc3246 100644 +--- a/src/torrent/common.h ++++ b/src/torrent/common.h +@@ -37,10 +37,13 @@ + #ifndef LIBTORRENT_COMMON_H + #define LIBTORRENT_COMMON_H + +-#include ++#include + #include + + struct sockaddr; ++struct sockaddr_in; ++struct sockaddr_in6; ++struct sockaddr_un; + + namespace torrent { + +diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h +index 2dcf2b37..cf43b0bf 100644 +--- a/src/torrent/connection_manager.h ++++ b/src/torrent/connection_manager.h +@@ -39,13 +39,13 @@ + #ifndef LIBTORRENT_CONNECTION_MANAGER_H + #define LIBTORRENT_CONNECTION_MANAGER_H + ++#include + #include + #include + #include + #include + #include + #include +-#include lt_tr1_functional + #include + + namespace torrent { +diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h +index 2b9c9412..fc212047 100644 +--- a/src/torrent/data/download_data.h ++++ b/src/torrent/data/download_data.h +@@ -37,7 +37,7 @@ + #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H + #define LIBTORRENT_DATA_DOWNLOAD_DATA_H + +-#include lt_tr1_functional ++#include + + #include + #include +diff --git a/src/torrent/data/file_list.cc b/src/torrent/data/file_list.cc +index 4721bdbd..2e334fa8 100644 +--- a/src/torrent/data/file_list.cc ++++ b/src/torrent/data/file_list.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include + #include + #include +diff --git a/src/torrent/data/transfer_list.h b/src/torrent/data/transfer_list.h +index 0a359b5e..9813af12 100644 +--- a/src/torrent/data/transfer_list.h ++++ b/src/torrent/data/transfer_list.h +@@ -37,9 +37,10 @@ + #ifndef LIBTORRENT_TRANSFER_LIST_H + #define LIBTORRENT_TRANSFER_LIST_H + ++#include + #include ++ + #include +-#include lt_tr1_functional + + namespace torrent { + +diff --git a/src/torrent/download.cc b/src/torrent/download.cc +index edddedfb..f72c9351 100644 +--- a/src/torrent/download.cc ++++ b/src/torrent/download.cc +@@ -36,9 +36,7 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- +-#include ++#include + + #include "data/block.h" + #include "data/block_list.h" +diff --git a/src/torrent/download/choke_group.cc b/src/torrent/download/choke_group.cc +index a1540fc1..d9b25a9c 100644 +--- a/src/torrent/download/choke_group.cc ++++ b/src/torrent/download/choke_group.cc +@@ -37,7 +37,7 @@ + #include "config.h" + + #include +-#include lt_tr1_functional ++#include + + #include "choke_group.h" + #include "choke_queue.h" +diff --git a/src/torrent/download/choke_group.h b/src/torrent/download/choke_group.h +index 93fd1d02..50804b3e 100644 +--- a/src/torrent/download/choke_group.h ++++ b/src/torrent/download/choke_group.h +@@ -39,7 +39,7 @@ + + #include + #include +-#include ++#include + #include + #include + +diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc +index 3827e25e..7c00b686 100644 +--- a/src/torrent/download/choke_queue.cc ++++ b/src/torrent/download/choke_queue.cc +@@ -37,10 +37,9 @@ + #include "config.h" + + #include ++#include + #include + #include +-#include +-#include lt_tr1_functional + #include + + #include "protocol/peer_connection_base.h" +diff --git a/src/torrent/download/choke_queue.h b/src/torrent/download/choke_queue.h +index 973f6522..5e274a99 100644 +--- a/src/torrent/download/choke_queue.h ++++ b/src/torrent/download/choke_queue.h +@@ -39,10 +39,11 @@ + + #include + ++#include ++#include + #include + #include +-#include +-#include lt_tr1_functional ++ + #include + + namespace torrent { +diff --git a/src/torrent/download/group_entry.h b/src/torrent/download/group_entry.h +index e167ecbb..a7c9e429 100644 +--- a/src/torrent/download/group_entry.h ++++ b/src/torrent/download/group_entry.h +@@ -38,8 +38,9 @@ + #define LIBTORRENT_DOWNLOAD_GROUP_ENTRY_H + + #include ++#include + #include +-#include lt_tr1_functional ++ + #include + #include + +diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc +index bc6374d2..51434c91 100644 +--- a/src/torrent/download/resource_manager.cc ++++ b/src/torrent/download/resource_manager.cc +@@ -38,7 +38,6 @@ + + #include + #include +-#include lt_tr1_functional + #include + #include + #include +diff --git a/src/torrent/download/resource_manager.h b/src/torrent/download/resource_manager.h +index b2f861af..ba61b45f 100644 +--- a/src/torrent/download/resource_manager.h ++++ b/src/torrent/download/resource_manager.h +@@ -39,7 +39,7 @@ + + #include + #include +-#include ++#include + #include + + namespace torrent { +diff --git a/src/torrent/download_info.h b/src/torrent/download_info.h +index 341e4c25..2c4dbaf2 100644 +--- a/src/torrent/download_info.h ++++ b/src/torrent/download_info.h +@@ -37,10 +37,10 @@ + #ifndef LIBTORRENT_DOWNLOAD_INFO_H + #define LIBTORRENT_DOWNLOAD_INFO_H + ++#include ++#include + #include + #include +-#include +-#include lt_tr1_functional + + #include + #include +diff --git a/src/torrent/error.cc b/src/torrent/error.cc +index 5010c803..eea9bb83 100644 +--- a/src/torrent/error.cc ++++ b/src/torrent/error.cc +@@ -54,11 +54,15 @@ static const char* errorStrings[e_last + 1] = { + "unencrypted connection rejected", // eh_unencrypted_rejected + "invalid encryption method", // eh_invalid_encryption + "encryption sync failed", // eh_encryption_sync_failed +- "network error", // eh_network_error ++ "", // eh_ + "network unreachable", // eh_network_unreachable + "network timeout", // eh_network_timeout + "invalid message order", // eh_invalid_order + "too many failed chunks", // eh_toomanyfailed ++ "no peer info", // eh_no_peer_info ++ "network socket error", // eh_network_socket_error ++ "network read error", // eh_network_read_error ++ "network write error", // eh_network_write_error + + // "", // e_handshake_incoming + // "", // e_handshake_outgoing +diff --git a/src/torrent/error.h b/src/torrent/error.h +index f3fac463..295a595b 100644 +--- a/src/torrent/error.h ++++ b/src/torrent/error.h +@@ -55,11 +55,14 @@ const int e_handshake_invalid_value = 8; + const int e_handshake_unencrypted_rejected = 9; + const int e_handshake_invalid_encryption = 10; + const int e_handshake_encryption_sync_failed = 11; +-const int e_handshake_network_error = 12; + const int e_handshake_network_unreachable = 13; + const int e_handshake_network_timeout = 14; + const int e_handshake_invalid_order = 15; + const int e_handshake_toomanyfailed = 16; ++const int e_handshake_no_peer_info = 17; ++const int e_handshake_network_socket_error = 18; ++const int e_handshake_network_read_error = 19; ++const int e_handshake_network_write_error = 20; + + // const int e_handshake_incoming = 13; + // const int e_handshake_outgoing = 14; +@@ -69,7 +72,7 @@ const int e_handshake_toomanyfailed = 16; + // const int e_handshake_retry_plaintext = 18; + // const int e_handshake_retry_encrypted = 19; + +-const int e_last = 16; ++const int e_last = 20; + + const char* strerror(int err) LIBTORRENT_EXPORT; + +diff --git a/src/torrent/event.cc b/src/torrent/event.cc +new file mode 100644 +index 00000000..e68974ea +--- /dev/null ++++ b/src/torrent/event.cc +@@ -0,0 +1,19 @@ ++#include "config.h" ++ ++#include "event.h" ++ ++#include "torrent/exceptions.h" ++#include "torrent/net/fd.h" ++ ++namespace torrent { ++ ++void ++Event::close_file_descriptor() { ++ if (!is_open()) ++ throw internal_error("Tried to close already closed file descriptor on event type " + std::string(type_name())); ++ ++ fd_close(m_fileDesc); ++ m_fileDesc = -1; ++} ++ ++} +diff --git a/src/torrent/event.h b/src/torrent/event.h +index f3549762..73f87e46 100644 +--- a/src/torrent/event.h ++++ b/src/torrent/event.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_TORRENT_EVENT_H + #define LIBTORRENT_TORRENT_EVENT_H + +@@ -43,26 +7,48 @@ namespace torrent { + + class LIBTORRENT_EXPORT Event { + public: +- virtual ~Event() {} ++ Event(); ++ virtual ~Event(); + +- // These are not virtual as the fd is heavily used in select based +- // polling, thus fast access is critical to performance. +- int file_descriptor() const { return m_fileDesc; } ++ // TODO: Disable override. ++ bool is_open() const; + +- virtual void event_read() = 0; +- virtual void event_write() = 0; +- virtual void event_error() = 0; ++ int file_descriptor() const; + +- // Require all event types to define this function. +- virtual const char* type_name() const { return "default"; } ++ virtual void event_read() = 0; ++ virtual void event_write() = 0; ++ virtual void event_error() = 0; + +- // Event closed? ++ // TODO: Require all to define their ownh typename. ++ virtual const char* type_name() const { return "default"; } + + protected: +- int m_fileDesc; +- bool m_ipv6_socket; ++ void close_file_descriptor(); ++ void set_file_descriptor(int fd); ++ ++ int m_fileDesc; ++ ++ // TODO: Deprecate. ++ bool m_ipv6_socket; + }; + ++inline Event::Event() : m_fileDesc(-1), m_ipv6_socket(false) {} ++inline Event::~Event() {} ++inline bool Event::is_open() const { return file_descriptor() != -1; } ++inline int Event::file_descriptor() const { return m_fileDesc; } ++inline void Event::set_file_descriptor(int fd) { m_fileDesc = fd; } ++ ++// Defined in 'src/globals.cc'. ++[[gnu::weak]] void poll_event_open(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_close(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_closed(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_insert_read(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_insert_write(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_insert_error(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_remove_read(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_remove_write(Event* event) LIBTORRENT_EXPORT; ++[[gnu::weak]] void poll_event_remove_error(Event* event) LIBTORRENT_EXPORT; ++ + } + + #endif +diff --git a/src/torrent/http.h b/src/torrent/http.h +index c68d3933..c605afa5 100644 +--- a/src/torrent/http.h ++++ b/src/torrent/http.h +@@ -38,9 +38,9 @@ + #define LIBTORRENT_HTTP_H + + #include ++#include + #include + #include +-#include lt_tr1_functional + #include + + namespace torrent { +diff --git a/src/torrent/net/Makefile.am b/src/torrent/net/Makefile.am +index 51999d19..35dd4774 100644 +--- a/src/torrent/net/Makefile.am ++++ b/src/torrent/net/Makefile.am +@@ -1,11 +1,25 @@ + noinst_LTLIBRARIES = libsub_torrentnet.la + + libsub_torrentnet_la_SOURCES = \ ++ address_info.cc \ ++ address_info.h \ ++ fd.cc \ ++ fd.h \ ++ socket_address.cc \ ++ socket_address.h \ + socket_address_key.cc \ +- socket_address_key.h ++ socket_address_key.h \ ++ socket_event.cc \ ++ socket_event.h \ ++ types.h + + AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir) + + libtorrentincludedir = $(includedir)/torrent/net + libtorrentinclude_HEADERS = \ +- socket_address_key.h ++ address_info.h \ ++ fd.h \ ++ socket_address.h \ ++ socket_address_key.h \ ++ socket_event.h \ ++ types.h +diff --git a/src/torrent/net/address_info.cc b/src/torrent/net/address_info.cc +new file mode 100644 +index 00000000..25a51ebd +--- /dev/null ++++ b/src/torrent/net/address_info.cc +@@ -0,0 +1,43 @@ ++#include "config.h" ++ ++#include "address_info.h" ++ ++namespace torrent { ++ ++int ++ai_get_addrinfo(const char* nodename, const char* servname, const addrinfo* hints, ai_unique_ptr& res) { ++ addrinfo* ai; ++ int err = ::getaddrinfo(nodename, servname, hints, &ai); ++ ++ if (err != 0) ++ return err; ++ ++ res.reset(ai); ++ return 0; ++} ++ ++sa_unique_ptr ++ai_get_first_sa(const char* nodename, const char* servname, const addrinfo* hints) { ++ ai_unique_ptr aip; ++ ++ if (ai_get_addrinfo(nodename, servname, hints, aip) != 0) ++ return nullptr; ++ ++ return sa_copy(aip->ai_addr); ++} ++ ++int ++ai_each_inet_inet6_first(const char* nodename, ai_sockaddr_func lambda) { ++ int err; ++ ai_unique_ptr ai; ++ ++ // TODO: Change to a single call using hints with both inet/inet6. ++ if ((err = ai_get_addrinfo(nodename, NULL, ai_make_hint(0, PF_INET, SOCK_STREAM).get(), ai)) != 0 && ++ (err = ai_get_addrinfo(nodename, NULL, ai_make_hint(0, PF_INET6, SOCK_STREAM).get(), ai)) != 0) ++ return err; ++ ++ lambda(ai->ai_addr); ++ return 0; ++} ++ ++} +diff --git a/src/torrent/net/address_info.h b/src/torrent/net/address_info.h +new file mode 100644 +index 00000000..c0b1c082 +--- /dev/null ++++ b/src/torrent/net/address_info.h +@@ -0,0 +1,69 @@ ++#ifndef LIBTORRENT_NET_ADDRESS_INFO_H ++#define LIBTORRENT_NET_ADDRESS_INFO_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace torrent { ++ ++struct ai_deleter { ++ void operator()(addrinfo* ai) const { freeaddrinfo(ai); } ++}; ++ ++typedef std::unique_ptr ai_unique_ptr; ++typedef std::unique_ptr c_ai_unique_ptr; ++typedef std::function ai_sockaddr_func; ++ ++inline void ai_clear(addrinfo* ai); ++inline ai_unique_ptr ai_make_hint(int flags, int family, int socktype); ++ ++int ai_get_addrinfo(const char* nodename, const char* servname, const addrinfo* hints, ai_unique_ptr& res) LIBTORRENT_EXPORT; ++ ++// Helper functions: ++ ++// TODO: Consider servname "0". ++// TODO: ai_get_first_sa_err that returns a tuple? ++sa_unique_ptr ai_get_first_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) LIBTORRENT_EXPORT; ++ ++int ai_each_inet_inet6_first(const char* nodename, ai_sockaddr_func lambda) LIBTORRENT_EXPORT; ++ ++// Get all addrinfo's, iterate, etc. ++ ++// ++// Safe conversion from unique_ptr arguments: ++// ++ ++inline void aip_clear(ai_unique_ptr& aip) { return ai_clear(aip.get()); } ++ ++inline int aip_get_addrinfo(const char* nodename, const char* servname, const ai_unique_ptr& hints, ai_unique_ptr& res) { return ai_get_addrinfo(nodename, servname, hints.get(), res); } ++inline int aip_get_addrinfo(const char* nodename, const char* servname, const c_ai_unique_ptr& hints, ai_unique_ptr& res) { return ai_get_addrinfo(nodename, servname, hints.get(), res); } ++ ++// ++// Implementations: ++// ++ ++inline void ++ai_clear(addrinfo* ai) { ++ std::memset(ai, 0, sizeof(addrinfo)); ++} ++ ++inline ai_unique_ptr ++ai_make_hint(int flags, int family, int socktype) { ++ ai_unique_ptr aip(new addrinfo); ++ ++ aip_clear(aip); ++ aip->ai_flags = flags; ++ aip->ai_family = family; ++ aip->ai_socktype = socktype; ++ ++ return aip; ++} ++ ++} ++ ++#endif +diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc +new file mode 100644 +index 00000000..07c91779 +--- /dev/null ++++ b/src/torrent/net/fd.cc +@@ -0,0 +1,209 @@ ++#include "config.h" ++ ++#include "fd.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "torrent/exceptions.h" ++#include "torrent/net/socket_address.h" ++#include "torrent/utils/log.h" ++ ++#define LT_LOG(log_fmt, ...) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt, __VA_ARGS__); ++#define LT_LOG_FLAG(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (flags:0x%x)", flags); ++#define LT_LOG_FLAG_ERROR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (flags:0x%x errno:%i message:'%s')", \ ++ flags, errno, std::strerror(errno)); ++#define LT_LOG_FD(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd); ++#define LT_LOG_FD_ERROR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \ ++ fd, errno, std::strerror(errno)); ++#define LT_LOG_FD_SOCKADDR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \ ++ fd, sa_pretty_str(sa).c_str()); ++#define LT_LOG_FD_SOCKADDR_ERROR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s errno:%i message:'%s')", \ ++ fd, sa_pretty_str(sa).c_str(), errno, std::strerror(errno)); ++#define LT_LOG_FD_FLAG(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (flags:0x%x)", fd, flags); ++#define LT_LOG_FD_FLAG_ERROR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (flags:0x%x errno:%i message:'%s')", \ ++ fd, flags, errno, std::strerror(errno)); ++#define LT_LOG_FD_VALUE(log_fmt, value) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (value:%i)", fd, (int)value); ++#define LT_LOG_FD_VALUE_ERROR(log_fmt, value) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (value:%i errno:%i message:'%s')", \ ++ fd, (int)value, errno, std::strerror(errno)); ++ ++namespace torrent { ++ ++int fd__accept(int socket, sockaddr *address, socklen_t *address_len) { return ::accept(socket, address, address_len); } ++int fd__bind(int socket, const sockaddr *address, socklen_t address_len) { return ::bind(socket, address, address_len); } ++int fd__close(int fildes) { return ::close(fildes); } ++int fd__connect(int socket, const sockaddr *address, socklen_t address_len) { return ::connect(socket, address, address_len); } ++int fd__fcntl_int(int fildes, int cmd, int arg) { return ::fcntl(fildes, cmd, arg); } ++int fd__listen(int socket, int backlog) { return ::listen(socket, backlog); } ++int fd__setsockopt_int(int socket, int level, int option_name, int option_value) { return ::setsockopt(socket, level, option_name, &option_value, sizeof(int)); } ++int fd__socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); } ++ ++int ++fd_open(fd_flags flags) { ++ int domain; ++ int protocol; ++ ++ if (!fd_valid_flags(flags)) ++ throw internal_error("torrent::fd_open failed: invalid fd_flags"); ++ ++ if ((flags & fd_flag_stream)) { ++ domain = SOCK_STREAM; ++ protocol = IPPROTO_TCP; ++ } else { ++ LT_LOG_FLAG("fd_open missing socket type"); ++ errno = EINVAL; ++ return -1; ++ } ++ ++ int fd = -1; ++ ++ if (fd == -1 && !(flags & fd_flag_v4only)) { ++ LT_LOG_FLAG("fd_open opening ipv6 socket"); ++ fd = fd__socket(PF_INET6, domain, protocol); ++ } ++ ++ if (fd == -1 && !(flags & fd_flag_v6only)) { ++ LT_LOG_FLAG("fd_open opening ipv4 socket"); ++ fd = fd__socket(PF_INET, domain, protocol); ++ } ++ ++ if (fd == -1) { ++ LT_LOG_FLAG_ERROR("fd_open failed to open socket"); ++ return -1; ++ } ++ ++ if ((flags & fd_flag_v6only) && !fd_set_v6only(fd, true)) { ++ LT_LOG_FD_FLAG_ERROR("fd_open failed to set v6only"); ++ fd_close(fd); ++ return -1; ++ } ++ ++ if ((flags & fd_flag_nonblock) && !fd_set_nonblock(fd)) { ++ LT_LOG_FD_FLAG_ERROR("fd_open failed to set nonblock"); ++ fd_close(fd); ++ return -1; ++ } ++ ++ if ((flags & fd_flag_reuse_address) && !fd_set_reuse_address(fd, true)) { ++ LT_LOG_FD_FLAG_ERROR("fd_open failed to set reuse_address"); ++ fd_close(fd); ++ return -1; ++ } ++ ++ LT_LOG_FD_FLAG("fd_open succeeded"); ++ return fd; ++} ++ ++void ++fd_close(int fd) { ++ if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) ++ throw internal_error("torrent::fd_close: tried to close stdin/out/err"); ++ ++ if (fd__close(fd) == -1) ++ throw internal_error("torrent::fd_close: " + std::string(strerror(errno))); ++ ++ LT_LOG_FD("fd_close succeeded"); ++} ++ ++fd_sap_tuple ++fd_accept(int fd) { ++ sa_unique_ptr sap = sa_make_inet6(); ++ socklen_t socklen = sap_length(sap); ++ ++ int accept_fd = fd__accept(fd, sap.get(), &socklen); ++ ++ if (accept_fd == -1) { ++ LT_LOG_FD_ERROR("fd_accept failed"); ++ return fd_sap_tuple{-1, nullptr}; ++ } ++ ++ return fd_sap_tuple{accept_fd, std::move(sap)}; ++} ++ ++bool ++fd_bind(int fd, const sockaddr* sa) { ++ if (fd__bind(fd, sa, sa_length(sa)) == -1) { ++ LT_LOG_FD_SOCKADDR_ERROR("fd_bind failed"); ++ return false; ++ } ++ ++ LT_LOG_FD_SOCKADDR("fd_bind succeeded"); ++ return true; ++} ++ ++bool ++fd_connect(int fd, const sockaddr* sa) { ++ if (fd__connect(fd, sa, sa_length(sa)) == 0) { ++ LT_LOG_FD_SOCKADDR("fd_connect succeeded"); ++ return true; ++ } ++ ++ if (errno == EINPROGRESS) { ++ LT_LOG_FD_SOCKADDR("fd_connect succeeded and in progress"); ++ return true; ++ } ++ ++ LT_LOG_FD_SOCKADDR_ERROR("fd_connect failed"); ++ return false; ++} ++ ++bool ++fd_listen(int fd, int backlog) { ++ if (fd__listen(fd, backlog) == -1) { ++ LT_LOG_FD_VALUE_ERROR("fd_listen failed", backlog); ++ return false; ++ } ++ ++ LT_LOG_FD_VALUE("fd_listen succeeded", backlog); ++ return true; ++} ++ ++bool ++fd_set_nonblock(int fd) { ++ if (fd__fcntl_int(fd, F_SETFL, O_NONBLOCK) == -1) { ++ LT_LOG_FD_ERROR("fd_set_nonblock failed"); ++ return false; ++ } ++ ++ LT_LOG_FD("fd_set_nonblock succeeded"); ++ return true; ++} ++ ++bool ++fd_set_reuse_address(int fd, bool state) { ++ if (fd__setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, state) == -1) { ++ LT_LOG_FD_VALUE_ERROR("fd_set_reuse_address failed", state); ++ return false; ++ } ++ ++ LT_LOG_FD_VALUE("fd_set_reuse_address succeeded", state); ++ return true; ++} ++ ++bool ++fd_set_v6only(int fd, bool state) { ++ if (fd__setsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, state) == -1) { ++ LT_LOG_FD_VALUE_ERROR("fd_set_v6only failed", state); ++ return false; ++ } ++ ++ LT_LOG_FD_VALUE("fd_set_v6only succeeded", state); ++ return true; ++} ++ ++} +diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h +new file mode 100644 +index 00000000..a7094646 +--- /dev/null ++++ b/src/torrent/net/fd.h +@@ -0,0 +1,63 @@ ++#ifndef LIBTORRENT_NET_FD_H ++#define LIBTORRENT_NET_FD_H ++ ++#include ++#include ++#include ++ ++namespace torrent { ++ ++enum fd_flags : int { ++ fd_flag_stream = 0x1, ++ fd_flag_nonblock = 0x10, ++ fd_flag_reuse_address = 0x20, ++ fd_flag_v4only = 0x40, ++ fd_flag_v6only = 0x80, ++ fd_flag_all = 0xff, ++}; ++ ++constexpr bool fd_valid_flags(fd_flags flags); ++ ++int fd_open(fd_flags flags) LIBTORRENT_EXPORT; ++void fd_close(int fd) LIBTORRENT_EXPORT; ++ ++fd_sap_tuple fd_accept(int fd) LIBTORRENT_EXPORT; ++ ++bool fd_bind(int fd, const sockaddr* sa) LIBTORRENT_EXPORT; ++bool fd_connect(int fd, const sockaddr* sa) LIBTORRENT_EXPORT; ++bool fd_listen(int fd, int backlog) LIBTORRENT_EXPORT; ++ ++bool fd_set_nonblock(int fd) LIBTORRENT_EXPORT; ++bool fd_set_reuse_address(int fd, bool state) LIBTORRENT_EXPORT; ++bool fd_set_v6only(int fd, bool state) LIBTORRENT_EXPORT; ++ ++[[gnu::weak]] int fd__accept(int socket, sockaddr *address, socklen_t *address_len) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__bind(int socket, const sockaddr *address, socklen_t address_len) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__close(int fildes) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__connect(int socket, const sockaddr *address, socklen_t address_len) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__fcntl_int(int fildes, int cmd, int arg) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__listen(int socket, int backlog) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__setsockopt_int(int socket, int level, int option_name, int option_value) LIBTORRENT_EXPORT; ++[[gnu::weak]] int fd__socket(int domain, int type, int protocol) LIBTORRENT_EXPORT; ++ ++constexpr fd_flags ++operator |(fd_flags lhs, fd_flags rhs) { ++ return static_cast(static_cast(lhs) | static_cast(rhs)); ++} ++ ++inline fd_flags& ++operator |=(fd_flags& lhs, fd_flags rhs) { ++ return (lhs = lhs | rhs); ++} ++ ++constexpr bool ++fd_valid_flags(fd_flags flags) { ++ return ++ (flags & fd_flag_stream) && ++ !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) && ++ !(flags & ~(fd_flag_all)); ++} ++ ++} ++ ++#endif +diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc +new file mode 100644 +index 00000000..c36ba0ae +--- /dev/null ++++ b/src/torrent/net/socket_address.cc +@@ -0,0 +1,559 @@ ++#include "config.h" ++ ++#include "socket_address.h" ++ ++#include ++#include ++#include ++ ++// TODO: Deprecate. ++#include "rak/socket_address.h" ++ ++#include "torrent/exceptions.h" ++ ++namespace torrent { ++ ++constexpr uint32_t ++sin6_addr32_index(const sockaddr_in6* sa, unsigned int index) { ++ return ++ (sa->sin6_addr.s6_addr[index * 4 + 0] << 24) + ++ (sa->sin6_addr.s6_addr[index * 4 + 1] << 16) + ++ (sa->sin6_addr.s6_addr[index * 4 + 2] << 8) + ++ (sa->sin6_addr.s6_addr[index * 4 + 3] << 0); ++} ++ ++inline void ++sin6_addr32_set(sockaddr_in6* sa, unsigned int index, uint32_t value) { ++ sa->sin6_addr.s6_addr[index * 4 + 0] = (value >> 24); ++ sa->sin6_addr.s6_addr[index * 4 + 1] = (value >> 16); ++ sa->sin6_addr.s6_addr[index * 4 + 2] = (value >> 8); ++ sa->sin6_addr.s6_addr[index * 4 + 3] = (value >> 0); ++} ++ ++inline in6_addr ++sin6_make_addr32(uint32_t addr0, uint32_t addr1, uint32_t addr2, uint32_t addr3) { ++ uint32_t addr32[4]; ++ addr32[0] = htonl(addr0); ++ addr32[1] = htonl(addr1); ++ addr32[2] = htonl(addr2); ++ addr32[3] = htonl(addr3); ++ ++ return *reinterpret_cast(addr32); ++} ++ ++bool ++sa_is_unspec(const sockaddr* sa) { ++ return sa != NULL && sa->sa_family == AF_UNSPEC; ++} ++ ++bool ++sa_is_inet(const sockaddr* sa) { ++ return sa != NULL && sa->sa_family == AF_INET; ++} ++ ++bool ++sa_is_inet6(const sockaddr* sa) { ++ return sa != NULL && sa->sa_family == AF_INET6; ++} ++ ++bool ++sa_is_inet_inet6(const sockaddr* sa) { ++ return sa != NULL && (sa->sa_family == AF_INET || sa->sa_family == AF_INET6); ++} ++ ++bool ++sa_is_any(const sockaddr* sa) { ++ switch (sa->sa_family) { ++ case AF_INET: ++ return sin_is_any(reinterpret_cast(sa)); ++ case AF_INET6: ++ if (sa_is_v4mapped(sa)) ++ return sin6_addr32_index(reinterpret_cast(sa), 3) == htonl(INADDR_ANY); ++ return sin6_is_any(reinterpret_cast(sa)); ++ default: ++ return true; ++ } ++} ++ ++bool ++sin_is_any(const sockaddr_in* sa) { ++ return sa->sin_addr.s_addr == htonl(INADDR_ANY); ++} ++ ++bool ++sin6_is_any(const sockaddr_in6* sa) { ++ return std::memcmp(&sa->sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0; ++} ++ ++bool ++sa_is_broadcast(const sockaddr* sa) { ++ switch (sa->sa_family) { ++ case AF_INET: ++ return sin_is_broadcast(reinterpret_cast(sa)); ++ case AF_INET6: ++ if (sa_is_v4mapped(sa)) ++ return sin6_addr32_index(reinterpret_cast(sa), 3) == htonl(INADDR_BROADCAST); ++ return false; ++ default: ++ return false; ++ } ++} ++ ++bool ++sin_is_broadcast(const sockaddr_in* sa) { ++ return sa->sin_addr.s_addr == htonl(INADDR_BROADCAST); ++} ++ ++bool ++sa_is_v4mapped(const sockaddr* sa) { ++ return sa != NULL && sa->sa_family == AF_INET6 && sin6_is_v4mapped(reinterpret_cast(sa)); ++} ++ ++bool ++sin6_is_v4mapped(const sockaddr_in6* sa) { ++ return sa != NULL && IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr); ++} ++ ++bool ++sa_is_port_any(const sockaddr* sa) { ++ return sa_port(sa) == 0; ++} ++ ++size_t ++sa_length(const sockaddr* sa) { ++ switch(sa->sa_family) { ++ case AF_INET: ++ return sizeof(sockaddr_in); ++ case AF_INET6: ++ return sizeof(sockaddr_in6); ++ default: ++ return sizeof(sa); ++ } ++} ++ ++sa_unique_ptr ++sa_make_unspec() { ++ sa_unique_ptr sa(new sockaddr); ++ ++ std::memset(sa.get(), 0, sizeof(sa)); ++ sa.get()->sa_family = AF_UNSPEC; ++ ++ return sa; ++} ++ ++sa_unique_ptr ++sa_make_inet() { ++ return sa_unique_ptr(reinterpret_cast(sin_make().release())); ++} ++ ++sa_unique_ptr ++sa_make_inet6() { ++ return sa_unique_ptr(reinterpret_cast(sin6_make().release())); ++} ++ ++sa_unique_ptr ++sa_make_unix(const std::string& pathname) { ++ if (!pathname.empty()) ++ throw internal_error("torrent::sa_make_unix: function not implemented"); ++ ++ sun_unique_ptr sunp(new sockaddr_un); ++ ++ std::memset(sunp.get(), 0, sizeof(sockaddr_un)); ++ sunp->sun_family = AF_UNIX; ++ // TODO: verify length, copy pathname ++ ++ return sa_unique_ptr(reinterpret_cast(sunp.release())); ++} ++ ++sa_unique_ptr ++sa_convert(const sockaddr* sa) { ++ if (sa == NULL) ++ return sa_make_unspec(); ++ ++ switch(sa->sa_family) { ++ case AF_INET: ++ return sa_copy_in(reinterpret_cast(sa)); ++ case AF_INET6: ++ if (sin6_is_v4mapped(reinterpret_cast(sa))) ++ return sa_from_v4mapped_in6(reinterpret_cast(sa)); ++ ++ return sa_copy_in6(reinterpret_cast(sa)); ++ case AF_UNSPEC: ++ return sa_make_unspec(); ++ default: ++ throw internal_error("torrent::sa_convert: sockaddr is not a valid family"); ++ } ++} ++ ++sa_unique_ptr ++sa_copy(const sockaddr* sa) { ++ if (sa == nullptr) ++ throw internal_error("torrent::sa_copy: sockaddr is a nullptr"); ++ ++ switch(sa->sa_family) { ++ case AF_INET: ++ return sa_copy_in(reinterpret_cast(sa)); ++ case AF_INET6: ++ return sa_copy_in6(reinterpret_cast(sa)); ++ case AF_UNSPEC: ++ return sa_make_unspec(); ++ default: ++ throw internal_error("torrent::sa_copy: sockaddr is not a valid family"); ++ } ++} ++ ++sa_unique_ptr ++sa_copy_in(const sockaddr_in* sa) { ++ sa_unique_ptr result(reinterpret_cast(new sockaddr_in)); ++ std::memcpy(result.get(), sa, sizeof(sockaddr_in)); ++ return result; ++} ++ ++sa_unique_ptr ++sa_copy_in6(const sockaddr_in6* sa) { ++ sa_unique_ptr result(reinterpret_cast(new sockaddr_in6)); ++ std::memcpy(result.get(), sa, sizeof(sockaddr_in6)); ++ return result; ++} ++ ++sa_unique_ptr ++sa_copy_addr(const sockaddr* sa, uint16_t port) { ++ if (sa == nullptr) ++ throw internal_error("torrent::sa_copy_addr: sockaddr is a nullptr"); ++ ++ switch(sa->sa_family) { ++ case AF_INET: ++ return sa_copy_addr_in(reinterpret_cast(sa), port); ++ case AF_INET6: ++ return sa_copy_addr_in6(reinterpret_cast(sa), port); ++ case AF_UNSPEC: ++ return sa_make_unspec(); ++ default: ++ throw internal_error("torrent::sa_copy_addr: sockaddr is not a valid family"); ++ } ++} ++ ++sa_unique_ptr ++sa_copy_addr_in(const sockaddr_in* sa, uint16_t port) { ++ sa_unique_ptr result(reinterpret_cast(new sockaddr_in)); ++ std::memset(result.get(), 0, sizeof(sockaddr_in)); ++ reinterpret_cast(result.get())->sin_family = AF_INET; ++ reinterpret_cast(result.get())->sin_addr = sa->sin_addr; ++ reinterpret_cast(result.get())->sin_port = htons(port); ++ return result; ++} ++ ++sa_unique_ptr ++sa_copy_addr_in6(const sockaddr_in6* sa, uint16_t port) { ++ sa_unique_ptr result(reinterpret_cast(new sockaddr_in6)); ++ std::memset(result.get(), 0, sizeof(sockaddr_in6)); ++ reinterpret_cast(result.get())->sin6_family = AF_INET6; ++ std::memcpy(&reinterpret_cast(result.get())->sin6_addr, &sa->sin6_addr, sizeof(in6_addr)); ++ reinterpret_cast(result.get())->sin6_port = htons(port); ++ return result; ++} ++ ++sin_unique_ptr ++sin_copy(const sockaddr_in* sa) { ++ sin_unique_ptr result(new sockaddr_in); ++ std::memcpy(result.get(), sa, sizeof(sockaddr_in)); ++ return result; ++} ++ ++sin6_unique_ptr ++sin6_copy(const sockaddr_in6* sa) { ++ sin6_unique_ptr result(new sockaddr_in6); ++ std::memcpy(result.get(), sa, sizeof(sockaddr_in6)); ++ return result; ++} ++ ++sin_unique_ptr ++sin_make() { ++ sin_unique_ptr sa(new sockaddr_in); ++ std::memset(sa.get(), 0, sizeof(sockaddr_in)); ++ sa.get()->sin_family = AF_INET; ++ ++ return sa; ++} ++ ++sin6_unique_ptr ++sin6_make() { ++ sin6_unique_ptr sa(new sockaddr_in6); ++ std::memset(sa.get(), 0, sizeof(sockaddr_in6)); ++ sa.get()->sin6_family = AF_INET6; ++ ++ return sa; ++} ++ ++sa_unique_ptr ++sa_from_v4mapped(const sockaddr* sa) { ++ if (!sa_is_inet6(sa)) ++ throw internal_error("torrent::sa_from_v4mapped: sockaddr is not inet6"); ++ ++ return sa_from_in(sin_from_v4mapped_in6(reinterpret_cast(sa))); ++} ++ ++sa_unique_ptr ++sa_to_v4mapped(const sockaddr* sa) { ++ if (!sa_is_inet(sa)) ++ throw internal_error("torrent::sa_to_v4mapped: sockaddr is not inet"); ++ ++ return sa_from_in6(sin6_to_v4mapped_in(reinterpret_cast(sa))); ++} ++ ++sin_unique_ptr ++sin_from_v4mapped_in6(const sockaddr_in6* sin6) { ++ if (!sin6_is_v4mapped(sin6)) ++ throw internal_error("torrent::sin6_is_v4mapped: sockaddr_in6 is not v4mapped"); ++ ++ sin_unique_ptr result = sin_make(); ++ result.get()->sin_addr.s_addr = reinterpret_cast(htonl(sin6_addr32_index(sin6, 3))); ++ result.get()->sin_port = sin6->sin6_port; ++ ++ return result; ++} ++ ++sin6_unique_ptr ++sin6_to_v4mapped_in(const sockaddr_in* sin) { ++ sin6_unique_ptr result = sin6_make(); ++ ++ result.get()->sin6_addr = sin6_make_addr32(0, 0, 0xffff, ntohl(sin->sin_addr.s_addr)); ++ result.get()->sin6_port = sin->sin_port; ++ ++ return result; ++} ++ ++sin_unique_ptr ++sin_from_sa(sa_unique_ptr&& sap) { ++ if (!sap_is_inet(sap)) ++ throw internal_error("torrent::sin_from_sa: sockaddr is nullptr or not inet"); ++ ++ return sin_unique_ptr(reinterpret_cast(sap.release())); ++} ++ ++sin6_unique_ptr ++sin6_from_sa(sa_unique_ptr&& sap) { ++ if (!sap_is_inet6(sap)) ++ throw internal_error("torrent::sin6_from_sa: sockaddr is nullptr or not inet6"); ++ ++ return sin6_unique_ptr(reinterpret_cast(sap.release())); ++} ++ ++c_sin_unique_ptr ++sin_from_c_sa(c_sa_unique_ptr&& sap) { ++ if (!sap_is_inet(sap)) ++ throw internal_error("torrent::sin_from_c_sa: sockaddr is nullptr or not inet"); ++ ++ return c_sin_unique_ptr(reinterpret_cast(sap.release())); ++} ++ ++c_sin6_unique_ptr ++sin6_from_c_sa(sa_unique_ptr&& sap) { ++ if (!sap_is_inet6(sap)) ++ throw internal_error("torrent::sin6_from_c_sa: sockaddr is nullptr or not inet6"); ++ ++ return c_sin6_unique_ptr(reinterpret_cast(sap.release())); ++} ++ ++void ++sa_clear_inet6(sockaddr_in6* sa) { ++ std::memset(sa, 0, sizeof(sockaddr_in6)); ++ sa->sin6_family = AF_INET6; ++} ++ ++uint16_t ++sa_port(const sockaddr* sa) { ++ if (sa == NULL) ++ return 0; ++ ++ switch(sa->sa_family) { ++ case AF_INET: ++ return ntohs(reinterpret_cast(sa)->sin_port); ++ case AF_INET6: ++ return ntohs(reinterpret_cast(sa)->sin6_port); ++ default: ++ return 0; ++ } ++} ++ ++void ++sa_set_port(sockaddr* sa, uint16_t port) { ++ switch(sa->sa_family) { ++ case AF_INET: ++ reinterpret_cast(sa)->sin_port = htons(port); ++ return; ++ case AF_INET6: ++ reinterpret_cast(sa)->sin6_port = htons(port); ++ return; ++ default: ++ throw internal_error("torrent::sa_set_port: invalid family type"); ++ } ++} ++ ++bool ++sa_equal(const sockaddr* lhs, const sockaddr* rhs) { ++ switch(rhs->sa_family) { ++ case AF_INET: ++ case AF_INET6: ++ case AF_UNSPEC: ++ break; ++ default: ++ throw internal_error("torrent::sa_equal: rhs sockaddr is not a valid family"); ++ } ++ ++ switch(lhs->sa_family) { ++ case AF_INET: ++ return lhs->sa_family == rhs->sa_family && ++ sin_equal(reinterpret_cast(lhs), reinterpret_cast(rhs)); ++ case AF_INET6: ++ return lhs->sa_family == rhs->sa_family && ++ sin6_equal(reinterpret_cast(lhs), reinterpret_cast(rhs)); ++ case AF_UNSPEC: ++ return lhs->sa_family == rhs->sa_family; ++ default: ++ throw internal_error("torrent::sa_equal: lhs sockaddr is not a valid family"); ++ } ++} ++ ++bool ++sin_equal(const sockaddr_in* lhs, const sockaddr_in* rhs) { ++ return lhs->sin_port == rhs->sin_port && lhs->sin_addr.s_addr == rhs->sin_addr.s_addr; ++} ++ ++bool ++sin6_equal(const sockaddr_in6* lhs, const sockaddr_in6* rhs) { ++ return lhs->sin6_port == rhs->sin6_port && std::equal(lhs->sin6_addr.s6_addr, lhs->sin6_addr.s6_addr + 16, rhs->sin6_addr.s6_addr); ++} ++ ++bool ++sa_equal_addr(const sockaddr* lhs, const sockaddr* rhs) { ++ switch(rhs->sa_family) { ++ case AF_INET: ++ case AF_INET6: ++ case AF_UNSPEC: ++ break; ++ default: ++ throw internal_error("torrent::sa_equal_addr: rhs sockaddr is not a valid family"); ++ } ++ ++ switch(lhs->sa_family) { ++ case AF_INET: ++ return lhs->sa_family == rhs->sa_family && ++ sin_equal_addr(reinterpret_cast(lhs), reinterpret_cast(rhs)); ++ case AF_INET6: ++ return lhs->sa_family == rhs->sa_family && ++ sin6_equal_addr(reinterpret_cast(lhs), reinterpret_cast(rhs)); ++ case AF_UNSPEC: ++ return lhs->sa_family == rhs->sa_family; ++ default: ++ throw internal_error("torrent::sa_equal_addr: lhs sockaddr is not a valid family"); ++ } ++} ++ ++bool ++sin_equal_addr(const sockaddr_in* lhs, const sockaddr_in* rhs) { ++ return lhs->sin_addr.s_addr == rhs->sin_addr.s_addr; ++} ++ ++bool ++sin6_equal_addr(const sockaddr_in6* lhs, const sockaddr_in6* rhs) { ++ return std::equal(lhs->sin6_addr.s6_addr, lhs->sin6_addr.s6_addr + 16, rhs->sin6_addr.s6_addr); ++} ++ ++std::string ++sa_addr_str(const sockaddr* sa) { ++ if (sa == NULL) ++ return "unspec"; ++ ++ switch (sa->sa_family) { ++ case AF_INET: ++ return sin_addr_str(reinterpret_cast(sa)); ++ case AF_INET6: ++ return sin6_addr_str(reinterpret_cast(sa)); ++ case AF_UNSPEC: ++ return "unspec"; ++ default: ++ return "invalid"; ++ } ++} ++ ++std::string ++sin_addr_str(const sockaddr_in* sa) { ++ char buffer[INET_ADDRSTRLEN]; ++ ++ if (inet_ntop(AF_INET, &sa->sin_addr, buffer, INET_ADDRSTRLEN) == NULL) ++ return "inet_error"; ++ ++ return buffer; ++} ++ ++ ++std::string ++sin6_addr_str(const sockaddr_in6* sa) { ++ char buffer[INET6_ADDRSTRLEN]; ++ ++ if (inet_ntop(AF_INET6, &sa->sin6_addr, buffer, INET6_ADDRSTRLEN) == NULL) ++ return "inet6_error"; ++ ++ return buffer; ++} ++ ++std::string ++sa_pretty_str(const sockaddr* sa) { ++ if (sa == nullptr) ++ return "nullptr"; ++ ++ switch (sa->sa_family) { ++ case AF_INET: ++ return sin_pretty_str(reinterpret_cast(sa)); ++ case AF_INET6: ++ return sin6_pretty_str(reinterpret_cast(sa)); ++ case AF_UNSPEC: ++ return "unspec"; ++ default: ++ return "invalid"; ++ } ++} ++ ++std::string ++sin_pretty_str(const sockaddr_in* sa) { ++ auto result = sin_addr_str(sa); ++ ++ if (sa->sin_port != 0) ++ result += ':' + std::to_string(ntohs(sa->sin_port)); ++ ++ return result; ++} ++ ++std::string ++sin6_pretty_str(const sockaddr_in6* sa) { ++ auto result = "[" + sin6_addr_str(sa) + "]"; ++ ++ if (sa->sin6_port != 0) ++ result += ':' + std::to_string(ntohs(sa->sin6_port)); ++ ++ return result; ++} ++ ++// Deprecated: ++ ++void ++sa_inet_mapped_inet6(const sockaddr_in* sa, sockaddr_in6* mapped) { ++ uint32_t addr32[4]; ++ addr32[0] = 0; ++ addr32[1] = 0; ++ addr32[2] = htonl(0xffff); ++ addr32[3] = sa->sin_addr.s_addr; ++ ++ sa_clear_inet6(mapped); ++ ++ mapped->sin6_addr = *reinterpret_cast(addr32); ++ mapped->sin6_port = sa->sin_port; ++} ++ ++std::string ++sa_pretty_address_str(const sockaddr* sa) { ++ return sa_pretty_str(sa); ++} ++ ++} +diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h +new file mode 100644 +index 00000000..f64aee68 +--- /dev/null ++++ b/src/torrent/net/socket_address.h +@@ -0,0 +1,229 @@ ++#ifndef LIBTORRENT_NET_SOCKET_ADDRESS_H ++#define LIBTORRENT_NET_SOCKET_ADDRESS_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++namespace torrent { ++ ++bool sa_is_unspec(const sockaddr* sa) LIBTORRENT_EXPORT; ++bool sa_is_inet(const sockaddr* sa) LIBTORRENT_EXPORT; ++bool sa_is_inet6(const sockaddr* sa) LIBTORRENT_EXPORT; ++bool sa_is_inet_inet6(const sockaddr* sa) LIBTORRENT_EXPORT; ++ ++bool sa_is_any(const sockaddr* sa) LIBTORRENT_EXPORT; ++bool sin_is_any(const sockaddr_in* sa) LIBTORRENT_EXPORT; ++bool sin6_is_any(const sockaddr_in6* sa) LIBTORRENT_EXPORT; ++ ++bool sa_is_broadcast(const sockaddr* sa) LIBTORRENT_EXPORT; ++bool sin_is_broadcast(const sockaddr_in* sa) LIBTORRENT_EXPORT; ++ ++bool sa_is_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT; ++bool sin6_is_v4mapped(const sockaddr_in6* sa) LIBTORRENT_EXPORT; ++ ++bool sa_is_port_any(const sockaddr* sa) LIBTORRENT_EXPORT; ++ ++size_t sa_length(const sockaddr* sa) LIBTORRENT_EXPORT; ++ ++sa_unique_ptr sa_make_unspec() LIBTORRENT_EXPORT; ++sa_unique_ptr sa_make_inet() LIBTORRENT_EXPORT; ++sa_unique_ptr sa_make_inet6() LIBTORRENT_EXPORT; ++sa_unique_ptr sa_make_unix(const std::string& pathname) LIBTORRENT_EXPORT; ++ ++sa_unique_ptr sa_convert(const sockaddr* sa) LIBTORRENT_EXPORT; ++ ++sa_unique_ptr sa_copy(const sockaddr* sa) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_copy_in(const sockaddr_in* sa) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_copy_in6(const sockaddr_in6* sa) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_copy_addr(const sockaddr* sa, uint16_t port = 0) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_copy_addr_in(const sockaddr_in* sa, uint16_t port = 0) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_copy_addr_in6(const sockaddr_in6* sa, uint16_t port = 0) LIBTORRENT_EXPORT; ++sin_unique_ptr sin_copy(const sockaddr_in* sa) LIBTORRENT_EXPORT; ++sin6_unique_ptr sin6_copy(const sockaddr_in6* sa) LIBTORRENT_EXPORT; ++ ++sin_unique_ptr sin_make() LIBTORRENT_EXPORT; ++sin6_unique_ptr sin6_make() LIBTORRENT_EXPORT; ++ ++sa_unique_ptr sa_from_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_to_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_from_v4mapped_in6(const sockaddr_in6* sin6) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_to_v4mapped_in(const sockaddr_in* sin) LIBTORRENT_EXPORT; ++sin_unique_ptr sin_from_v4mapped_in6(const sockaddr_in6* sin6) LIBTORRENT_EXPORT; ++sin6_unique_ptr sin6_to_v4mapped_in(const sockaddr_in* sin) LIBTORRENT_EXPORT; ++ ++sa_unique_ptr sa_from_in(sin_unique_ptr&& sinp) LIBTORRENT_EXPORT; ++c_sa_unique_ptr sa_from_in(c_sin_unique_ptr&& sinp) LIBTORRENT_EXPORT; ++sa_unique_ptr sa_from_in6(sin6_unique_ptr&& sin6p) LIBTORRENT_EXPORT; ++c_sa_unique_ptr sa_from_in6(c_sin6_unique_ptr&& sin6p) LIBTORRENT_EXPORT; ++sin_unique_ptr sin_from_sa(sa_unique_ptr&& sap) LIBTORRENT_EXPORT; ++sin6_unique_ptr sin6_from_sa(sa_unique_ptr&& sap) LIBTORRENT_EXPORT; ++c_sin_unique_ptr sin_from_c_sa(c_sa_unique_ptr&& sap) LIBTORRENT_EXPORT; ++c_sin6_unique_ptr sin6_from_c_sa(c_sa_unique_ptr&& sap) LIBTORRENT_EXPORT; ++ ++void sa_clear_inet6(sockaddr_in6* sa) LIBTORRENT_EXPORT; ++ ++uint16_t sa_port(const sockaddr* sa) LIBTORRENT_EXPORT; ++void sa_set_port(sockaddr* sa, uint16_t port) LIBTORRENT_EXPORT; ++ ++bool sa_equal(const sockaddr* lhs, const sockaddr* rhs) LIBTORRENT_EXPORT; ++bool sin_equal(const sockaddr_in* lhs, const sockaddr_in* rhs) LIBTORRENT_EXPORT; ++bool sin6_equal(const sockaddr_in6* lhs, const sockaddr_in6* rhs) LIBTORRENT_EXPORT; ++ ++bool sa_equal_addr(const sockaddr* lhs, const sockaddr* rhs) LIBTORRENT_EXPORT; ++bool sin_equal_addr(const sockaddr_in* lhs, const sockaddr_in* rhs) LIBTORRENT_EXPORT; ++bool sin6_equal_addr(const sockaddr_in6* lhs, const sockaddr_in6* rhs) LIBTORRENT_EXPORT; ++ ++std::string sa_addr_str(const sockaddr* sa) LIBTORRENT_EXPORT; ++std::string sin_addr_str(const sockaddr_in* sa) LIBTORRENT_EXPORT; ++std::string sin6_addr_str(const sockaddr_in6* sa) LIBTORRENT_EXPORT; ++ ++std::string sa_pretty_str(const sockaddr* sa) LIBTORRENT_EXPORT; ++std::string sin_pretty_str(const sockaddr_in* sa) LIBTORRENT_EXPORT; ++std::string sin6_pretty_str(const sockaddr_in6* sa) LIBTORRENT_EXPORT; ++ ++// Rename/replace: ++void sa_inet_mapped_inet6(const sockaddr_in* sa, sockaddr_in6* mapped) LIBTORRENT_EXPORT; ++ ++std::string sa_pretty_address_str(const sockaddr* sa) LIBTORRENT_EXPORT; ++ ++// ++// Tuples: ++// ++ ++bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_EXPORT; ++ ++// ++// Safe conversion from unique_ptr arguments: ++// ++ ++inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); } ++inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); } ++inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } ++inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } ++inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); } ++inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); } ++inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); } ++inline bool sap_is_inet_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); } ++ ++inline bool sap_is_any(const sa_unique_ptr& sap) { return sa_is_any(sap.get()); } ++inline bool sap_is_any(const c_sa_unique_ptr& sap) { return sa_is_any(sap.get()); } ++inline bool sinp_is_any(const sin_unique_ptr& sinp) { return sin_is_any(sinp.get()); } ++inline bool sinp_is_any(const c_sin_unique_ptr& sinp) { return sin_is_any(sinp.get()); } ++inline bool sinp6_is_any(const sin6_unique_ptr& sin6p) { return sin6_is_any(sin6p.get()); } ++inline bool sinp6_is_any(const c_sin6_unique_ptr& sin6p) { return sin6_is_any(sin6p.get()); } ++ ++inline bool sap_is_broadcast(const sa_unique_ptr& sap) { return sa_is_broadcast(sap.get()); } ++inline bool sap_is_broadcast(const c_sa_unique_ptr& sap) { return sa_is_broadcast(sap.get()); } ++inline bool sinp_is_broadcast(const sin_unique_ptr& sap) { return sin_is_broadcast(sap.get()); } ++inline bool sinp_is_broadcast(const c_sin_unique_ptr& sap) { return sin_is_broadcast(sap.get()); } ++ ++inline bool sap_is_v4mapped(const sa_unique_ptr& sap) { return sa_is_v4mapped(sap.get()); } ++inline bool sap_is_v4mapped(const c_sa_unique_ptr& sap) { return sa_is_v4mapped(sap.get()); } ++inline bool sinp6_is_v4mapped(const sin6_unique_ptr& sin6p) { return sin6_is_v4mapped(sin6p.get()); } ++inline bool sinp6_is_v4mapped(const c_sin6_unique_ptr& sin6p) { return sin6_is_v4mapped(sin6p.get()); } ++ ++inline bool sap_is_port_any(const sa_unique_ptr& sap) { return sa_is_port_any(sap.get()); } ++inline bool sap_is_port_any(const c_sa_unique_ptr& sap) { return sa_is_port_any(sap.get()); } ++ ++inline size_t sap_length(const sa_unique_ptr& sap) { return sa_length(sap.get()); } ++inline size_t sap_length(const c_sa_unique_ptr& sap) { return sa_length(sap.get()); } ++ ++inline sa_unique_ptr sap_copy(const sa_unique_ptr& sap) { return sa_copy(sap.get()); } ++inline sa_unique_ptr sap_copy(const c_sa_unique_ptr& sap) { return sa_copy(sap.get()); } ++inline sa_unique_ptr sap_copy_addr(const sa_unique_ptr& sap, uint16_t port = 0) { return sa_copy_addr(sap.get(), port); } ++inline sa_unique_ptr sap_copy_addr(const c_sa_unique_ptr& sap, uint16_t port = 0) { return sa_copy_addr(sap.get(), port); } ++inline sa_unique_ptr sap_copy_in(const sin_unique_ptr& sinp) { return sa_copy_in(sinp.get()); } ++inline sa_unique_ptr sap_copy_in(const c_sin_unique_ptr& sinp) { return sa_copy_in(sinp.get()); } ++inline sa_unique_ptr sap_copy_in6(const sin6_unique_ptr& sin6p) { return sa_copy_in6(sin6p.get()); } ++inline sa_unique_ptr sap_copy_in6(const c_sin6_unique_ptr& sin6p) { return sa_copy_in6(sin6p.get()); } ++ ++inline sa_unique_ptr sap_from_v4mapped(const sa_unique_ptr& sap) { return sa_from_v4mapped(sap.get()); } ++inline sa_unique_ptr sap_from_v4mapped(const c_sa_unique_ptr& sap) { return sa_from_v4mapped(sap.get()); } ++inline sa_unique_ptr sap_to_v4mapped(const sa_unique_ptr& sap) { return sa_to_v4mapped(sap.get()); } ++inline sa_unique_ptr sap_to_v4mapped(const c_sa_unique_ptr& sap) { return sa_to_v4mapped(sap.get()); } ++inline sin_unique_ptr sinp_from_v4mapped_in6(const sin6_unique_ptr& sin6p) { return sin_from_v4mapped_in6(sin6p.get()); } ++inline sin_unique_ptr sinp_from_v4mapped_in6(const c_sin6_unique_ptr& sin6p) { return sin_from_v4mapped_in6(sin6p.get()); } ++inline sin6_unique_ptr sin6p_to_v4mapped_in(const sin_unique_ptr& sinp) { return sin6_to_v4mapped_in(sinp.get()); } ++inline sin6_unique_ptr sin6p_to_v4mapped_in(const c_sin_unique_ptr& sinp) { return sin6_to_v4mapped_in(sinp.get()); } ++ ++inline uint16_t sap_port(const sa_unique_ptr& sap) { return sa_port(sap.get()); } ++inline uint16_t sap_port(const c_sa_unique_ptr& sap) { return sa_port(sap.get()); } ++inline void sap_set_port(const sa_unique_ptr& sap, uint16_t port) { sa_set_port(sap.get(), port); } ++ ++inline bool sap_equal(const sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); } ++inline bool sap_equal(const sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); } ++inline bool sap_equal(const c_sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); } ++inline bool sap_equal(const c_sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); } ++inline bool sinp_equal(const sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); } ++inline bool sinp_equal(const sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); } ++inline bool sinp_equal(const c_sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); } ++inline bool sinp_equal(const c_sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); } ++inline bool sin6p_equal(const sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); } ++inline bool sin6p_equal(const sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); } ++inline bool sin6p_equal(const c_sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); } ++inline bool sin6p_equal(const c_sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); } ++ ++inline bool sap_equal_addr(const sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); } ++inline bool sap_equal_addr(const sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); } ++inline bool sap_equal_addr(const c_sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); } ++inline bool sap_equal_addr(const c_sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); } ++inline bool sinp_equal_addr(const sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); } ++inline bool sinp_equal_addr(const sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); } ++inline bool sinp_equal_addr(const c_sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); } ++inline bool sinp_equal_addr(const c_sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); } ++inline bool sin6p_equal_addr(const sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); } ++inline bool sin6p_equal_addr(const sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); } ++inline bool sin6p_equal_addr(const c_sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); } ++inline bool sin6p_equal_addr(const c_sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); } ++ ++inline std::string sap_addr_str(const sa_unique_ptr& sap) { return sa_addr_str(sap.get()); } ++inline std::string sap_addr_str(const c_sa_unique_ptr& sap) { return sa_addr_str(sap.get()); } ++inline std::string sap_pretty_str(const sa_unique_ptr& sap) { return sa_pretty_str(sap.get()); } ++inline std::string sap_pretty_str(const c_sa_unique_ptr& sap) { return sa_pretty_str(sap.get()); } ++ ++// ++// Implementations: ++// ++ ++inline sa_unique_ptr ++sa_from_v4mapped_in6(const sockaddr_in6* sin6) { ++ return sa_from_in(sin_from_v4mapped_in6(sin6)); ++} ++ ++inline sa_unique_ptr ++sa_to_v4mapped_in(const sockaddr_in* sin) { ++ return sa_from_in6(sin6_to_v4mapped_in(sin)); ++} ++ ++inline sa_unique_ptr ++sa_from_in(sin_unique_ptr&& sinp) { ++ return sa_unique_ptr(reinterpret_cast(sinp.release())); ++} ++ ++inline c_sa_unique_ptr ++sa_from_in(c_sin_unique_ptr&& sinp) { ++ return c_sa_unique_ptr(reinterpret_cast(sinp.release())); ++} ++ ++inline sa_unique_ptr ++sa_from_in6(sin6_unique_ptr&& sin6p) { ++ return sa_unique_ptr(reinterpret_cast(sin6p.release())); ++} ++ ++inline c_sa_unique_ptr ++sa_from_in6(c_sin6_unique_ptr&& sin6p) { ++ return c_sa_unique_ptr(reinterpret_cast(sin6p.release())); ++} ++ ++inline bool ++fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) { ++ return std::get<0>(lhs) == std::get<0>(rhs) && sap_equal(std::get<1>(lhs), std::get<1>(rhs)); ++} ++ ++} ++ ++#endif +diff --git a/src/torrent/net/socket_address_key.h b/src/torrent/net/socket_address_key.h +index 9d6e0c49..0fd0feb3 100644 +--- a/src/torrent/net/socket_address_key.h ++++ b/src/torrent/net/socket_address_key.h +@@ -5,7 +5,7 @@ + #define LIBTORRENT_UTILS_SOCKET_ADDRESS_KEY_H + + #include +-#include ++#include + #include + + // Unique key for the socket address, excluding port numbers, etc. +diff --git a/src/torrent/net/socket_event.cc b/src/torrent/net/socket_event.cc +new file mode 100644 +index 00000000..e6805290 +--- /dev/null ++++ b/src/torrent/net/socket_event.cc +@@ -0,0 +1,29 @@ ++#include "config.h" ++ ++#include "socket_event.h" ++ ++#include "torrent/exceptions.h" ++ ++namespace torrent { ++ ++socket_event::~socket_event() { ++ if (is_open()) ++ throw internal_error("Called socket_event::~socket_event while still open on type " + std::string(type_name())); ++} ++ ++void ++socket_event::event_read() { ++ throw internal_error("Called unsupported socket_event::event_read on type " + std::string(type_name())); ++} ++ ++void ++socket_event::event_write() { ++ throw internal_error("Called unsupported socket_event::event_write on type " + std::string(type_name())); ++} ++ ++void ++socket_event::event_error() { ++ throw internal_error("Called unsupported socket_event::event_error on type " + std::string(type_name())); ++} ++ ++} +diff --git a/src/torrent/net/socket_event.h b/src/torrent/net/socket_event.h +new file mode 100644 +index 00000000..d9904bd6 +--- /dev/null ++++ b/src/torrent/net/socket_event.h +@@ -0,0 +1,31 @@ ++#ifndef LIBTORRENT_SOCKET_EVENT_H ++#define LIBTORRENT_SOCKET_EVENT_H ++ ++#include ++ ++#include "torrent/event.h" ++#include "torrent/net/socket_address.h" ++ ++namespace torrent { ++ ++class LIBTORRENT_EXPORT socket_event : public Event { ++public: ++ ~socket_event() override; ++ ++ const sockaddr* socket_address() const; ++ uint16_t socket_address_port() const; ++ ++ void event_read() override; ++ void event_write() override; ++ void event_error() override; ++ ++protected: ++ sa_unique_ptr m_socket_address; ++}; ++ ++inline const sockaddr* socket_event::socket_address() const { return m_socket_address.get(); } ++inline uint16_t socket_event::socket_address_port() const { return sap_port(m_socket_address); } ++ ++} ++ ++#endif +diff --git a/src/torrent/net/types.h b/src/torrent/net/types.h +new file mode 100644 +index 00000000..016e8b85 +--- /dev/null ++++ b/src/torrent/net/types.h +@@ -0,0 +1,33 @@ ++#ifndef LIBTORRENT_NET_TYPES_H ++#define LIBTORRENT_NET_TYPES_H ++ ++#include ++#include ++#include ++ ++struct sockaddr_in; ++struct sockaddr_in6; ++struct sockaddr_un; ++ ++namespace torrent { ++ ++typedef std::unique_ptr sa_unique_ptr; ++typedef std::unique_ptr sin_unique_ptr; ++typedef std::unique_ptr sin6_unique_ptr; ++typedef std::unique_ptr sun_unique_ptr; ++ ++typedef std::unique_ptr c_sa_unique_ptr; ++typedef std::unique_ptr c_sin_unique_ptr; ++typedef std::unique_ptr c_sin6_unique_ptr; ++typedef std::unique_ptr c_sun_unique_ptr; ++ ++typedef std::tuple> fd_sap_tuple; ++ ++struct listen_result_type { ++ int fd; ++ sa_unique_ptr address; ++}; ++ ++} ++ ++#endif +diff --git a/src/torrent/object.h b/src/torrent/object.h +index 3325a434..3f9fe7e4 100644 +--- a/src/torrent/object.h ++++ b/src/torrent/object.h +@@ -37,8 +37,9 @@ + #ifndef LIBTORRENT_OBJECT_H + #define LIBTORRENT_OBJECT_H + +-#include ++#include + #include ++#include + #include + #include + #include +@@ -162,6 +163,7 @@ public: + string_type& as_string() { check_throw(TYPE_STRING); return _string(); } + const string_type& as_string() const { check_throw(TYPE_STRING); return _string(); } + const string_type& as_string_c() const { check_throw(TYPE_STRING); return _string(); } ++ const char* as_c_str() const { check_throw(TYPE_STRING); return _string().c_str(); } + list_type& as_list() { check_throw(TYPE_LIST); return _list(); } + const list_type& as_list() const { check_throw(TYPE_LIST); return _list(); } + map_type& as_map() { check_throw(TYPE_MAP); return _map(); } +@@ -179,6 +181,8 @@ public: + raw_map& as_raw_map() { check_throw(TYPE_RAW_MAP); return _raw_map(); } + const raw_map& as_raw_map() const { check_throw(TYPE_RAW_MAP); return _raw_map(); } + ++ template T as_value_type(const char* err_msg) const { check_value_throw(err_msg); return _value(); } ++ + bool has_key(const key_type& k) const { check_throw(TYPE_MAP); return _map().find(k) != _map().end(); } + bool has_key_value(const key_type& k) const { check_throw(TYPE_MAP); return check(_map().find(k), TYPE_VALUE); } + bool has_key_string(const key_type& k) const { check_throw(TYPE_MAP); return check(_map().find(k), TYPE_STRING); } +@@ -246,6 +250,8 @@ public: + inline bool check(map_type::const_iterator itr, type_type t) const { return itr != _map().end() && itr->second.type() == t; } + inline void check_throw(type_type t) const { if (t != type()) throw bencode_error("Wrong object type."); } + ++ template void check_value_throw(const char* err_msg) const; ++ + uint32_t m_flags; + + #ifndef HAVE_STDCXX_0X +@@ -484,6 +490,19 @@ object_equal(const Object& left, const Object& right) { + } + } + ++template ++inline void ++Object::check_value_throw(const char* err_msg) const { ++ if (!std::numeric_limits::is_integer) ++ throw internal_error("Tried to check value with non-integer type."); ++ ++ if (!is_value()) ++ throw bencode_error(err_msg); ++ ++ if (!(_value() >= std::numeric_limits::min() && _value() <= std::numeric_limits::max())) ++ throw bencode_error(err_msg); ++} ++ + } + + #endif +diff --git a/src/torrent/peer/client_list.cc b/src/torrent/peer/client_list.cc +index c857f62d..9c18aa50 100644 +--- a/src/torrent/peer/client_list.cc ++++ b/src/torrent/peer/client_list.cc +@@ -37,8 +37,8 @@ + #include "config.h" + + #include ++#include + #include +-#include lt_tr1_functional + + #include "client_list.h" + #include "exceptions.h" +diff --git a/src/torrent/peer/connection_list.h b/src/torrent/peer/connection_list.h +index ec26835f..eb058784 100644 +--- a/src/torrent/peer/connection_list.h ++++ b/src/torrent/peer/connection_list.h +@@ -37,9 +37,10 @@ + #ifndef LIBTORRENT_PEER_CONNECTION_LIST_H + #define LIBTORRENT_PEER_CONNECTION_LIST_H + ++#include + #include + #include +-#include lt_tr1_functional ++ + #include + #include + +diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc +index aa60939a..080a7f13 100644 +--- a/src/torrent/peer/peer_list.cc ++++ b/src/torrent/peer/peer_list.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include + #include + #include +@@ -56,6 +54,8 @@ + + #define LT_LOG_EVENTS(log_fmt, ...) \ + lt_log_print_info(LOG_PEER_LIST_EVENTS, m_info, "peer_list", log_fmt, __VA_ARGS__); ++#define LT_LOG_ADDRESS(log_fmt, ...) \ ++ lt_log_print_info(LOG_PEER_LIST_ADDRESS, m_info, "peer_list", log_fmt, __VA_ARGS__); + #define LT_LOG_SA_FMT "'%s:%" PRIu16 "'" + + namespace torrent { +@@ -196,6 +196,7 @@ PeerList::insert_available(const void* al) { + for (; itr != last; itr++) { + if (!socket_address_key::is_comparable_sockaddr(itr->c_sockaddr()) || itr->port() == 0) { + invalid++; ++ LT_LOG_ADDRESS("skipped invalid address " LT_LOG_SA_FMT, itr->address_str().c_str(), itr->port()); + continue; + } + +@@ -242,6 +243,8 @@ PeerList::insert_available(const void* al) { + + inserted++; + m_available_list->push_back(&*itr); ++ ++ LT_LOG_ADDRESS("added available address " LT_LOG_SA_FMT, itr->address_str().c_str(), itr->port()); + } + + LT_LOG_EVENTS("inserted peers" +diff --git a/src/torrent/poll.h b/src/torrent/poll.h +index b12c8ec2..15a73897 100644 +--- a/src/torrent/poll.h ++++ b/src/torrent/poll.h +@@ -37,8 +37,7 @@ + #ifndef LIBTORRENT_TORRENT_POLL_H + #define LIBTORRENT_TORRENT_POLL_H + +-#include lt_tr1_functional +- ++#include + #include + + namespace torrent { +diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc +index 339c2c4f..fb70d247 100644 +--- a/src/torrent/torrent.cc ++++ b/src/torrent/torrent.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -139,8 +103,8 @@ main_thread() { + + ChunkManager* chunk_manager() { return manager->chunk_manager(); } + ClientList* client_list() { return manager->client_list(); } +-FileManager* file_manager() { return manager->file_manager(); } + ConnectionManager* connection_manager() { return manager->connection_manager(); } ++FileManager* file_manager() { return manager->file_manager(); } + DhtManager* dht_manager() { return manager->dht_manager(); } + ResourceManager* resource_manager() { return manager->resource_manager(); } + +@@ -189,8 +153,10 @@ download_add(Object* object) { + download->main()->set_metadata_size(metadata_size); + } + ++ std::string local_id = PEER_NAME + rak::generate_random(20 - std::string(PEER_NAME).size()); ++ + download->set_hash_queue(manager->hash_queue()); +- download->initialize(infoHash, PEER_NAME + rak::generate_random(20 - std::string(PEER_NAME).size())); ++ download->initialize(infoHash, local_id); + + // Add trackers, etc, after setting the info hash so that log + // entries look sane. +diff --git a/src/torrent/torrent.h b/src/torrent/torrent.h +index 7bcf88fe..0cdfdaa7 100644 +--- a/src/torrent/torrent.h ++++ b/src/torrent/torrent.h +@@ -44,6 +44,11 @@ + + namespace torrent { + ++class FileManager; ++class ResourceManager; ++ ++class thread_base; ++ + // Make sure you seed srandom and srand48 if available. + void initialize() LIBTORRENT_EXPORT; + +@@ -53,16 +58,12 @@ void cleanup() LIBTORRENT_EXPORT; + + bool is_inactive() LIBTORRENT_EXPORT; + +-class FileManager; +-class ResourceManager; +-class thread_base; +- + thread_base* main_thread() LIBTORRENT_EXPORT; + + ChunkManager* chunk_manager() LIBTORRENT_EXPORT; + ClientList* client_list() LIBTORRENT_EXPORT; +-FileManager* file_manager() LIBTORRENT_EXPORT; + ConnectionManager* connection_manager() LIBTORRENT_EXPORT; ++FileManager* file_manager() LIBTORRENT_EXPORT; + DhtManager* dht_manager() LIBTORRENT_EXPORT; + ResourceManager* resource_manager() LIBTORRENT_EXPORT; + +diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h +index a528ef6a..bd7546a9 100644 +--- a/src/torrent/tracker.h ++++ b/src/torrent/tracker.h +@@ -2,7 +2,7 @@ + #define LIBTORRENT_TRACKER_H + + #include +-#include ++#include + #include + + namespace torrent { +diff --git a/src/torrent/tracker_controller.h b/src/torrent/tracker_controller.h +index 70d1b43f..9452be0f 100644 +--- a/src/torrent/tracker_controller.h ++++ b/src/torrent/tracker_controller.h +@@ -37,8 +37,9 @@ + #ifndef LIBTORRENT_TRACKER_CONTROLLER_H + #define LIBTORRENT_TRACKER_CONTROLLER_H + ++#include + #include +-#include lt_tr1_functional ++ + #include + #include + +diff --git a/src/torrent/tracker_list.h b/src/torrent/tracker_list.h +index c6817b3a..bb06f8af 100644 +--- a/src/torrent/tracker_list.h ++++ b/src/torrent/tracker_list.h +@@ -38,10 +38,10 @@ + #define LIBTORRENT_TRACKER_LIST_H + + #include ++#include + #include + #include + #include +-#include lt_tr1_functional + + namespace torrent { + +diff --git a/src/torrent/utils/Makefile.am b/src/torrent/utils/Makefile.am +index 51c9a026..a48786c6 100644 +--- a/src/torrent/utils/Makefile.am ++++ b/src/torrent/utils/Makefile.am +@@ -8,10 +8,10 @@ libsub_torrentutils_la_SOURCES = \ + log.h \ + log_buffer.cc \ + log_buffer.h \ +- net.cc \ +- net.h \ + option_strings.cc \ + option_strings.h \ ++ random.cc \ ++ random.h \ + ranges.h \ + resume.cc \ + resume.h \ +@@ -32,7 +32,6 @@ libtorrentinclude_HEADERS = \ + extents.h \ + log.h \ + log_buffer.h \ +- net.h \ + option_strings.h \ + ranges.h \ + resume.h \ +diff --git a/src/torrent/utils/directory_events.h b/src/torrent/utils/directory_events.h +index 30fa0508..fd9246c5 100644 +--- a/src/torrent/utils/directory_events.h ++++ b/src/torrent/utils/directory_events.h +@@ -37,9 +37,10 @@ + #ifndef LIBTORRENT_DIRECTORY_EVENTS_H + #define LIBTORRENT_DIRECTORY_EVENTS_H + ++#include + #include + #include +-#include lt_tr1_functional ++ + #include + + namespace torrent { +diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc +index 6c605474..b855a2c6 100644 +--- a/src/torrent/utils/log.cc ++++ b/src/torrent/utils/log.cc +@@ -1,45 +1,6 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include "log.h" +-#include "log_buffer.h" + + #include "globals.h" + #include "torrent/exceptions.h" +@@ -54,8 +15,6 @@ + #include + #include + #include +-#include lt_tr1_functional +-#include lt_tr1_memory + + namespace torrent { + +@@ -232,7 +191,6 @@ log_initialize() { + + LOG_CASCADE(LOG_CRITICAL); + +- LOG_CASCADE(LOG_CONNECTION_CRITICAL); + LOG_CASCADE(LOG_PEER_CRITICAL); + LOG_CASCADE(LOG_SOCKET_CRITICAL); + LOG_CASCADE(LOG_STORAGE_CRITICAL); +@@ -240,7 +198,6 @@ log_initialize() { + LOG_CASCADE(LOG_TRACKER_CRITICAL); + LOG_CASCADE(LOG_TORRENT_CRITICAL); + +- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_CONNECTION_CRITICAL); + LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_PEER_CRITICAL); + LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_SOCKET_CRITICAL); + LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_STORAGE_CRITICAL); +@@ -248,6 +205,12 @@ log_initialize() { + LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_TRACKER_CRITICAL); + LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_TORRENT_CRITICAL); + ++ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_BIND); ++ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_FD); ++ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_FILTER); ++ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_HANDSHAKE); ++ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_LISTEN); ++ + LOG_LINK(LOG_DHT_ALL, LOG_DHT_MANAGER); + LOG_LINK(LOG_DHT_ALL, LOG_DHT_NODE); + LOG_LINK(LOG_DHT_ALL, LOG_DHT_ROUTER); +@@ -447,21 +410,4 @@ log_open_gz_file_output(const char* name, const char* filename, bool append) { + std::placeholders::_3)); + } + +-log_buffer* +-log_open_log_buffer(const char* name) { +- log_buffer* buffer = new log_buffer; +- +- try { +- log_open_output(name, std::bind(&log_buffer::lock_and_push_log, buffer, +- std::placeholders::_1, +- std::placeholders::_2, +- std::placeholders::_3)); +- return buffer; +- +- } catch (torrent::input_error& e) { +- delete buffer; +- throw; +- } +-} +- + } +diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h +index 0dfdc86b..fe6127d6 100644 +--- a/src/torrent/utils/log.h ++++ b/src/torrent/utils/log.h +@@ -1,47 +1,12 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_UTILS_LOG_H + #define LIBTORRENT_UTILS_LOG_H + ++#include + #include ++#include + #include + #include +-#include lt_tr1_array +-#include lt_tr1_functional ++ + #include + + namespace torrent { +@@ -55,13 +20,6 @@ enum { + LOG_INFO, + LOG_DEBUG, + +- LOG_CONNECTION_CRITICAL, +- LOG_CONNECTION_ERROR, +- LOG_CONNECTION_WARN, +- LOG_CONNECTION_NOTICE, +- LOG_CONNECTION_INFO, +- LOG_CONNECTION_DEBUG, +- + LOG_DHT_CRITICAL, + LOG_DHT_ERROR, + LOG_DHT_WARN, +@@ -113,6 +71,14 @@ enum { + + LOG_NON_CASCADING, + ++ LOG_CONNECTION, ++ LOG_CONNECTION_BIND, ++ LOG_CONNECTION_FD, ++ LOG_CONNECTION_FILTER, ++ LOG_CONNECTION_HANDSHAKE, ++ LOG_CONNECTION_LISTEN, ++ ++ // TODO: Rename dht_all to just dht. + LOG_DHT_ALL, + LOG_DHT_MANAGER, + LOG_DHT_NODE, +@@ -125,7 +91,10 @@ enum { + LOG_INSTRUMENTATION_POLLING, + LOG_INSTRUMENTATION_TRANSFERS, + ++ LOG_MOCK_CALLS, ++ + LOG_PEER_LIST_EVENTS, ++ LOG_PEER_LIST_ADDRESS, + + LOG_PROTOCOL_PIECE_EVENTS, + LOG_PROTOCOL_METADATA_EVENTS, +@@ -137,6 +106,8 @@ enum { + LOG_RPC_EVENTS, + LOG_RPC_DUMP, + ++ LOG_SYSTEM, ++ + LOG_UI_EVENTS, + + LOG_GROUP_MAX_SIZE +@@ -145,34 +116,32 @@ enum { + #define lt_log_is_valid(log_group) (torrent::log_groups[log_group].valid()) + + #define lt_log_print(log_group, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__); ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__); } + + #define lt_log_print_info(log_group, log_info, log_subsystem, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__); ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__); } + + #define lt_log_print_data(log_group, log_data, log_subsystem, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__); ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__); } + + #define lt_log_print_dump(log_group, log_dump_data, log_dump_size, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); \ ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); } + + #define lt_log_print_hash(log_group, log_hash, log_subsystem, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__); ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__); } + + #define lt_log_print_info_dump(log_group, log_dump_data, log_dump_size, log_info, log_subsystem, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); \ ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); } + + #define lt_log_print_subsystem(log_group, log_subsystem, ...) \ +- if (torrent::log_groups[log_group].valid()) \ +- torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__); +- +-class log_buffer; ++ { if (torrent::log_groups[log_group].valid()) \ ++ torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__); } + + typedef std::function log_slot; + +@@ -222,7 +191,7 @@ private: + + typedef std::array log_group_list; + +-extern log_group_list log_groups LIBTORRENT_EXPORT; ++extern log_group_list log_groups LIBTORRENT_EXPORT; + + void log_initialize() LIBTORRENT_EXPORT; + void log_cleanup() LIBTORRENT_EXPORT; +@@ -237,9 +206,8 @@ void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT; + void log_add_child(int group, int child) LIBTORRENT_EXPORT; + void log_remove_child(int group, int child) LIBTORRENT_EXPORT; + +-void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT; +-void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT; +-log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT; ++void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT; ++void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT; + + // + // Implementation: +diff --git a/src/torrent/utils/log_buffer.cc b/src/torrent/utils/log_buffer.cc +index f82d57e0..5bf159a4 100644 +--- a/src/torrent/utils/log_buffer.cc ++++ b/src/torrent/utils/log_buffer.cc +@@ -1,46 +1,8 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include "log_buffer.h" + +-#include +-#include lt_tr1_functional +- ++#include "log.h" + #include "globals.h" + + namespace torrent { +@@ -72,4 +34,19 @@ log_buffer::lock_and_push_log(const char* data, size_t length, int group) { + unlock(); + } + ++static void ++log_buffer_deleter(log_buffer* lb) { ++ delete lb; ++} ++ ++log_buffer_ptr ++log_open_log_buffer(const char* name) { ++ // TODO: Deregister when deleting. ++ auto buffer = log_buffer_ptr(new log_buffer, std::bind(&log_buffer_deleter, std::placeholders::_1)); ++ ++ log_open_output(name, std::bind(&log_buffer::lock_and_push_log, buffer.get(), ++ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); ++ return buffer; ++} ++ + } +diff --git a/src/torrent/utils/log_buffer.h b/src/torrent/utils/log_buffer.h +index befd780b..259e5910 100644 +--- a/src/torrent/utils/log_buffer.h ++++ b/src/torrent/utils/log_buffer.h +@@ -1,47 +1,11 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- +-#ifndef LIBTORRENT_UTILS_LOG_BUFFER_H +-#define LIBTORRENT_UTILS_LOG_BUFFER_H ++#ifndef LIBTORRENT_TORRENT_UTILS_LOG_BUFFER_H ++#define LIBTORRENT_TORRENT_UTILS_LOG_BUFFER_H + + #include + #include ++#include ++#include + #include +-#include lt_tr1_functional +-#include + + namespace torrent { + +@@ -57,9 +21,9 @@ struct log_entry { + std::string message; + }; + +-class LIBTORRENT_EXPORT log_buffer : private std::deque { ++class [[gnu::visibility("default")]] log_buffer : private std::deque { + public: +- typedef std::deque base_type; ++ typedef std::deque base_type; + typedef std::function slot_void; + + using base_type::iterator; +@@ -97,6 +61,10 @@ private: + slot_void m_slot_update; + }; + ++typedef std::unique_ptr> log_buffer_ptr; ++ ++[[gnu::visibility("default")]] log_buffer_ptr log_open_log_buffer(const char* name); ++ + } + + #endif +diff --git a/src/torrent/utils/net.cc b/src/torrent/utils/net.cc +deleted file mode 100644 +index 83c9b506..00000000 +--- a/src/torrent/utils/net.cc ++++ /dev/null +@@ -1,72 +0,0 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- +-#include "config.h" +- +-#include "net.h" +-#include "exceptions.h" +- +-#include +- +-namespace torrent { +- +-addrinfo* +-address_info_lookup(const char* hostname, int family, int socktype) { +- addrinfo hints; +- std::memset(&hints, 0, sizeof(addrinfo)); +- hints.ai_family = family; +- hints.ai_socktype = socktype; +- +- addrinfo* res = NULL; +- int err = ::getaddrinfo(hostname, NULL, &hints, &res); +- +- if (err) +- throw address_info_error(err); +- +- return res; +-} +- +-bool +-address_info_call(addrinfo* ai, int flags, slot_ai_success slot_success) { +- while (ai != NULL) { +- slot_success(ai->ai_addr, ai->ai_addrlen); +- return true; +- } +- +- return false; +-} +- +-} +diff --git a/src/torrent/utils/net.h b/src/torrent/utils/net.h +deleted file mode 100644 +index f5af7cc0..00000000 +--- a/src/torrent/utils/net.h ++++ /dev/null +@@ -1,56 +0,0 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- +-#ifndef LIBTORRENT_UTILS_NET_H +-#define LIBTORRENT_UTILS_NET_H +- +-#include +-#include lt_tr1_functional +- +-namespace torrent { +- +-typedef std::function slot_ai_success; +-//typedef std::function slot_ai_failure; +- +-// Throws address_info_error on lookup failure. +-addrinfo* address_info_lookup(const char* hostname, int family, int socktype); +-inline void address_info_free(addrinfo* ai) { ::freeaddrinfo(ai); } +- +-bool address_info_call(addrinfo* ai, int flags, slot_ai_success slot_success); +- +-} +- +-#endif +diff --git a/src/torrent/utils/option_strings.cc b/src/torrent/utils/option_strings.cc +index 5992cf37..101e2688 100644 +--- a/src/torrent/utils/option_strings.cc ++++ b/src/torrent/utils/option_strings.cc +@@ -62,7 +62,7 @@ struct option_pair { + unsigned int value; + }; + +-option_pair option_list_connection[] = { ++option_pair option_list_connection_type[] = { + { "leech", Download::CONNECTION_LEECH }, + { "seed", Download::CONNECTION_SEED }, + { "initial_seed", Download::CONNECTION_INITIAL_SEED }, +@@ -124,6 +124,19 @@ option_pair option_list_tracker_mode[] = { + { NULL, 0 } + }; + ++const char* option_list_handshake_connection[] = { ++ "none", ++ "incoming", ++ "outgoing_normal", ++ "outgoing_encrypted", ++ "outgoing_proxy", ++ "success", ++ "dropped", ++ "failed", ++ "retry_plaintext", ++ "retry_encrypted" ++}; ++ + const char* option_list_log_group[] = { + "critical", + "error", +@@ -132,13 +145,6 @@ const char* option_list_log_group[] = { + "info", + "debug", + +- "connection_critical", +- "connection_error", +- "connection_warn", +- "connection_notice", +- "connection_info", +- "connection_debug", +- + "dht_critical", + "dht_error", + "dht_warn", +@@ -190,6 +196,13 @@ const char* option_list_log_group[] = { + + "__non_cascading__", + ++ "connection", ++ "connection_bind", ++ "connection_fd", ++ "connection_filter", ++ "connection_hanshake", ++ "connection_listen", ++ + "dht_all", + "dht_manager", + "dht_node", +@@ -202,7 +215,10 @@ const char* option_list_log_group[] = { + "instrumentation_polling", + "instrumentation_transfers", + ++ "mock_calls", ++ + "peer_list_events", ++ "peer_list_address", + + "protocol_piece_events", + "protocol_metadata_events", +@@ -214,6 +230,8 @@ const char* option_list_log_group[] = { + "rpc_events", + "rpc_dump", + ++ "system", ++ + "ui_events", + + NULL +@@ -230,7 +248,7 @@ const char* option_list_tracker_event[] = { + }; + + option_pair* option_pair_lists[OPTION_START_COMPACT] = { +- option_list_connection, ++ option_list_connection_type, + option_list_heuristics, + option_list_heuristics_download, + option_list_heuristics_upload, +@@ -244,6 +262,7 @@ option_pair* option_pair_lists[OPTION_START_COMPACT] = { + { sizeof(single_name) / sizeof(const char*) - 1, single_name } + + option_single option_single_lists[OPTION_SINGLE_SIZE] = { ++ OPTION_SINGLE_ENTRY(option_list_handshake_connection), + OPTION_SINGLE_ENTRY(option_list_log_group), + OPTION_SINGLE_ENTRY(option_list_tracker_event), + }; +@@ -267,11 +286,11 @@ option_find_string(option_enum opt_enum, const char* name) { + } while (*++itr != NULL); + } + +- throw input_error("Invalid option name."); ++ throw input_error("Invalid option name."); + } + + const char* +-option_as_string(option_enum opt_enum, unsigned int value) { ++option_to_string(option_enum opt_enum, unsigned int value, const char* not_found) { + if (opt_enum < OPTION_START_COMPACT) { + option_pair* itr = option_pair_lists[opt_enum]; + +@@ -285,7 +304,27 @@ option_as_string(option_enum opt_enum, unsigned int value) { + return option_single_lists[opt_enum - OPTION_START_COMPACT].name[value]; + } + +- throw input_error("Invalid option value."); ++ return not_found; ++} ++ ++const char* ++option_to_string_or_throw(option_enum opt_enum, unsigned int value, const char* not_found) { ++ const char* result = option_to_string(opt_enum, value, NULL); ++ ++ if (result == NULL) ++ throw input_error(not_found); ++ else ++ return result; ++} ++ ++const char* ++option_as_string(option_enum opt_enum, unsigned int value) { ++ const char* result = option_to_string(opt_enum, value, NULL); ++ ++ if (result == NULL) ++ throw input_error("Invalid option value."); ++ else ++ return result; + } + + torrent::Object +diff --git a/src/torrent/utils/option_strings.h b/src/torrent/utils/option_strings.h +index 1b57efa8..f9e5ef77 100644 +--- a/src/torrent/utils/option_strings.h ++++ b/src/torrent/utils/option_strings.h +@@ -54,17 +54,22 @@ enum option_enum { + OPTION_IP_TOS, + OPTION_TRACKER_MODE, + ++ OPTION_HANDSHAKE_CONNECTION, + OPTION_LOG_GROUP, + OPTION_TRACKER_EVENT, + + OPTION_MAX_SIZE, +- OPTION_START_COMPACT = OPTION_LOG_GROUP, ++ OPTION_START_COMPACT = OPTION_HANDSHAKE_CONNECTION, + OPTION_SINGLE_SIZE = OPTION_MAX_SIZE - OPTION_START_COMPACT + }; + + int option_find_string(option_enum opt_enum, const char* name) LIBTORRENT_EXPORT; + inline int option_find_string_str(option_enum opt_enum, const std::string& name) { return option_find_string(opt_enum, name.c_str()); } + ++const char* option_to_string(option_enum opt_enum, unsigned int value, const char* not_found = "invalid") LIBTORRENT_EXPORT; ++const char* option_to_string_or_throw(option_enum opt_enum, unsigned int value, const char* not_found = "Invalid option value") LIBTORRENT_EXPORT; ++ ++// TODO: Deprecated. + const char* option_as_string(option_enum opt_enum, unsigned int value) LIBTORRENT_EXPORT; + + torrent::Object option_list_strings(option_enum opt_enum) LIBTORRENT_EXPORT; +diff --git a/src/torrent/utils/random.cc b/src/torrent/utils/random.cc +new file mode 100644 +index 00000000..6a045429 +--- /dev/null ++++ b/src/torrent/utils/random.cc +@@ -0,0 +1,29 @@ ++#include "config.h" ++ ++#include "random.h" ++ ++#include "torrent/exceptions.h" ++ ++namespace torrent { ++ ++// TODO: Replace with std and thread_local generator. ++ ++template ++T ++random_uniform_template(T min, T max) { ++ if (min > max) ++ throw internal_error("random_uniform: min > max"); ++ ++ if (min == max) ++ return min; ++ ++ std::random_device rd; ++ std::mt19937 mt(rd()); ++ ++ return min + std::uniform_int_distribution(min, max)(mt) % (max - min + 1); ++} ++ ++uint16_t random_uniform_uint16(uint16_t min, uint16_t max) { return random_uniform_template(min, max); } ++uint32_t random_uniform_uint32(uint32_t min, uint32_t max) { return random_uniform_template(min, max); } ++ ++} +diff --git a/src/torrent/utils/random.h b/src/torrent/utils/random.h +new file mode 100644 +index 00000000..d5992ab6 +--- /dev/null ++++ b/src/torrent/utils/random.h +@@ -0,0 +1,15 @@ ++#ifndef LIBTORRENT_TORRENT_UTILS_RANDOM_H ++#define LIBTORRENT_TORRENT_UTILS_RANDOM_H ++ ++#include ++#include ++#include ++ ++namespace torrent { ++ ++[[gnu::weak]] [[gnu::visibility("default")]] uint16_t random_uniform_uint16(uint16_t min = std::numeric_limits::min(), uint16_t max = std::numeric_limits::max()); ++[[gnu::weak]] [[gnu::visibility("default")]] uint32_t random_uniform_uint32(uint32_t min = std::numeric_limits::min(), uint32_t max = std::numeric_limits::max()); ++ ++} ++ ++#endif +diff --git a/src/torrent/utils/ranges.h b/src/torrent/utils/ranges.h +index e784b084..7b1f8cb0 100644 +--- a/src/torrent/utils/ranges.h ++++ b/src/torrent/utils/ranges.h +@@ -40,7 +40,6 @@ + #include + #include + +-// TODO: Use tr1 functional instead. + #include + + namespace torrent { +diff --git a/src/torrent/utils/resume.cc b/src/torrent/utils/resume.cc +index 3f528c14..f8467d54 100644 +--- a/src/torrent/utils/resume.cc ++++ b/src/torrent/utils/resume.cc +@@ -34,8 +34,6 @@ + // Skomakerveien 33 + // 3185 Skoppum, NORWAY + +-#define __STDC_FORMAT_MACROS +- + #include "config.h" + + #include +diff --git a/src/torrent/utils/signal_bitfield.h b/src/torrent/utils/signal_bitfield.h +index b9f57a60..ffa336d2 100644 +--- a/src/torrent/utils/signal_bitfield.h ++++ b/src/torrent/utils/signal_bitfield.h +@@ -37,7 +37,8 @@ + #ifndef LIBTORRENT_UTILS_SIGNAL_BITFIELD_H + #define LIBTORRENT_UTILS_SIGNAL_BITFIELD_H + +-#include lt_tr1_functional ++#include ++ + #include + + namespace torrent { +diff --git a/src/torrent/utils/thread_base.h b/src/torrent/utils/thread_base.h +index bfd443ae..b92a98ba 100644 +--- a/src/torrent/utils/thread_base.h ++++ b/src/torrent/utils/thread_base.h +@@ -37,11 +37,12 @@ + #ifndef LIBTORRENT_UTILS_THREAD_BASE_H + #define LIBTORRENT_UTILS_THREAD_BASE_H + ++#include + #include + #include ++ + #include + #include +-#include lt_tr1_functional + + namespace torrent { + +diff --git a/src/utils/instrumentation.cc b/src/utils/instrumentation.cc +index 729b20e2..178d6a19 100644 +--- a/src/utils/instrumentation.cc ++++ b/src/utils/instrumentation.cc +@@ -36,8 +36,6 @@ + + #include "config.h" + +-#define __STDC_FORMAT_MACROS +- + #include "instrumentation.h" + + namespace torrent { +diff --git a/src/utils/instrumentation.h b/src/utils/instrumentation.h +index 956429bf..11e77f6d 100644 +--- a/src/utils/instrumentation.h ++++ b/src/utils/instrumentation.h +@@ -37,9 +37,8 @@ + #ifndef LIBTORRENT_UTILS_INSTRUMENTATION_H + #define LIBTORRENT_UTILS_INSTRUMENTATION_H + +-#include lt_tr1_array +- + #include ++#include + + #include "torrent/common.h" + #include "torrent/utils/log.h" +diff --git a/src/utils/queue_buckets.h b/src/utils/queue_buckets.h +index de8584ff..b9174f27 100644 +--- a/src/utils/queue_buckets.h ++++ b/src/utils/queue_buckets.h +@@ -38,9 +38,9 @@ + #define LIBTORRENT_QUEUE_BUCKETS_H + + #include ++#include + #include +-#include lt_tr1_functional +-#include lt_tr1_array ++#include + + namespace torrent { + +diff --git a/src/utils/sha_fast.h b/src/utils/sha_fast.h +index f7ce3b87..eb357864 100644 +--- a/src/utils/sha_fast.h ++++ b/src/utils/sha_fast.h +@@ -41,7 +41,7 @@ + #ifndef _SHA_FAST_H_ + #define _SHA_FAST_H_ + +-#include ++#include + + namespace torrent { + +diff --git a/test/Makefile.am b/test/Makefile.am +index d7a9d5b3..b60a86a6 100644 +--- a/test/Makefile.am ++++ b/test/Makefile.am +@@ -18,6 +18,17 @@ LibTorrentTest_LDADD = \ + ../src/torrent/utils/libsub_torrentutils.la + + LibTorrentTest_SOURCES = \ ++ helpers/expect_fd.h \ ++ helpers/expect_utils.h \ ++ helpers/mock_compare.h \ ++ helpers/mock_function.cc \ ++ helpers/mock_function.h \ ++ helpers/network.h \ ++ helpers/progress_listener.cc \ ++ helpers/progress_listener.h \ ++ helpers/test_fixture.cc \ ++ helpers/test_fixture.h \ ++ \ + ../src/thread_disk.cc \ + ../src/thread_disk.h \ + \ +@@ -31,22 +42,28 @@ LibTorrentTest_SOURCES = \ + data/hash_check_queue_test.h \ + data/hash_queue_test.cc \ + data/hash_queue_test.h \ ++ \ ++ net/test_socket_listen.cc \ ++ net/test_socket_listen.h \ ++ \ + protocol/test_request_list.cc \ + protocol/test_request_list.h \ + \ +- torrent/net/test_socket_address_key.cc \ +- torrent/net/test_socket_address_key.h \ ++ torrent/net/test_address_info.cc \ ++ torrent/net/test_address_info.h \ ++ torrent/net/test_fd.cc \ ++ torrent/net/test_fd.h \ ++ torrent/net/test_socket_address.cc \ ++ torrent/net/test_socket_address.h \ + \ + torrent/utils/log_test.cc \ + torrent/utils/log_test.h \ +- torrent/utils/log_buffer_test.cc \ +- torrent/utils/log_buffer_test.h \ +- torrent/utils/net_test.cc \ +- torrent/utils/net_test.h \ + torrent/utils/option_strings_test.cc \ + torrent/utils/option_strings_test.h \ + torrent/utils/test_extents.cc \ + torrent/utils/test_extents.h \ ++ torrent/utils/test_log_buffer.cc \ ++ torrent/utils/test_log_buffer.h \ + torrent/utils/test_queue_buckets.cc \ + torrent/utils/test_queue_buckets.h \ + torrent/utils/test_uri_parser.cc \ +diff --git a/test/data/hash_check_queue_test.cc b/test/data/hash_check_queue_test.cc +index c6bdeaec..4b15245e 100644 +--- a/test/data/hash_check_queue_test.cc ++++ b/test/data/hash_check_queue_test.cc +@@ -1,7 +1,7 @@ + #include "config.h" + ++#include + #include +-#include lt_tr1_functional + + #include "data/hash_queue_node.h" + #include "utils/sha1.h" +diff --git a/test/data/hash_queue_test.cc b/test/data/hash_queue_test.cc +index 287c28e9..d7ce3ba8 100644 +--- a/test/data/hash_queue_test.cc ++++ b/test/data/hash_queue_test.cc +@@ -1,7 +1,7 @@ + #include "config.h" + ++#include + #include +-#include lt_tr1_functional + + #include "data/hash_queue_node.h" + #include "torrent/chunk_manager.h" +diff --git a/test/helpers/expect_fd.h b/test/helpers/expect_fd.h +new file mode 100644 +index 00000000..178cbabc +--- /dev/null ++++ b/test/helpers/expect_fd.h +@@ -0,0 +1,107 @@ ++#ifndef LIBTORRENT_HELPER_EXPECT_FD_H ++#define LIBTORRENT_HELPER_EXPECT_FD_H ++ ++#include "helpers/mock_function.h" ++ ++#include ++#include ++#include ++#include ++ ++typedef std::vector sap_cache_type; ++ ++inline const sockaddr* ++sap_cache_copy_addr_c_ptr(sap_cache_type& sap_cache, const torrent::c_sa_unique_ptr& sap, uint16_t port = 0) { ++ sap_cache.push_back(torrent::sap_copy_addr(sap, port)); ++ return sap_cache.back().get(); ++} ++ ++inline void ++expect_event_open_re(int idx) { ++ mock_expect(&torrent::poll_event_open, mock_compare_map::begin_pointer + idx); ++ mock_expect(&torrent::poll_event_insert_read, mock_compare_map::begin_pointer + idx); ++ mock_expect(&torrent::poll_event_insert_error, mock_compare_map::begin_pointer + idx); ++} ++ ++inline void ++expect_event_closed_fd(int idx, int fd) { ++ mock_expect(&torrent::fd__close, 0, fd); ++ mock_expect(&torrent::poll_event_closed, mock_compare_map::begin_pointer + idx); ++} ++ ++inline void ++expect_fd_inet_tcp(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++} ++ ++inline void ++expect_fd_inet6_tcp(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++} ++ ++inline void ++expect_fd_inet_tcp_nonblock(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK); ++} ++ ++inline void ++expect_fd_inet6_tcp_nonblock(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK); ++} ++ ++inline void ++expect_fd_inet_tcp_nonblock_reuseaddr(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK); ++ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true); ++} ++ ++inline void ++expect_fd_inet6_tcp_nonblock_reuseaddr(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK); ++ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true); ++} ++ ++inline void ++expect_fd_inet6_tcp_v6only_nonblock(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true); ++ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK); ++} ++ ++inline void ++expect_fd_inet6_tcp_v6only_nonblock_reuseaddr(int fd) { ++ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP); ++ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true); ++ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK); ++ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true); ++} ++ ++inline void ++expect_fd_bind_connect(int fd, const torrent::c_sa_unique_ptr& bind_sap, const torrent::c_sa_unique_ptr& connect_sap) { ++ mock_expect(&torrent::fd__bind, 0, fd, bind_sap.get(), (socklen_t)torrent::sap_length(bind_sap)); ++ mock_expect(&torrent::fd__connect, 0, fd, connect_sap.get(), (socklen_t)torrent::sap_length(connect_sap)); ++} ++ ++inline void ++expect_fd_bind_fail_range(int fd, sap_cache_type& sap_cache, const torrent::c_sa_unique_ptr& sap, uint16_t first_port, uint16_t last_port) { ++ do { ++ mock_expect(&torrent::fd__bind, -1, fd, sap_cache_copy_addr_c_ptr(sap_cache, sap, first_port), (socklen_t)torrent::sap_length(sap)); ++ } while (first_port++ != last_port); ++} ++ ++inline void ++expect_fd_bind_listen(int fd, const torrent::c_sa_unique_ptr& sap) { ++ mock_expect(&torrent::fd__bind, 0, fd, sap.get(), (socklen_t)torrent::sap_length(sap)); ++ mock_expect(&torrent::fd__listen, 0, fd, SOMAXCONN); ++} ++ ++inline void ++expect_fd_connect(int fd, const torrent::c_sa_unique_ptr& sap) { ++ mock_expect(&torrent::fd__connect, 0, fd, sap.get(), (socklen_t)torrent::sap_length(sap)); ++} ++ ++#endif +diff --git a/test/helpers/expect_utils.h b/test/helpers/expect_utils.h +new file mode 100644 +index 00000000..c84a11e0 +--- /dev/null ++++ b/test/helpers/expect_utils.h +@@ -0,0 +1,13 @@ ++#ifndef LIBTORRENT_HELPER_EXPECT_UTILS_H ++#define LIBTORRENT_HELPER_EXPECT_UTILS_H ++ ++#include "helpers/mock_function.h" ++ ++#include ++ ++inline void ++expect_random_uniform_uint16(uint16_t result, uint16_t first, uint16_t last) { ++ mock_expect(&torrent::random_uniform_uint16, result, first, last); ++} ++ ++#endif +diff --git a/test/helpers/mock_compare.h b/test/helpers/mock_compare.h +new file mode 100644 +index 00000000..3ea90305 +--- /dev/null ++++ b/test/helpers/mock_compare.h +@@ -0,0 +1,96 @@ ++#ifndef LIBTORRENT_HELPERS_MOCK_COMPARE_H ++#define LIBTORRENT_HELPERS_MOCK_COMPARE_H ++ ++#include ++#include ++#include ++#include ++ ++// Compare arguments to mock functions with what is expected. The lhs ++// are the expected arguments, rhs are the ones called with. ++ ++template ++inline bool mock_compare_arg(Arg lhs, Arg rhs) { return lhs == rhs; } ++ ++template ++typename std::enable_if::type ++mock_compare_tuple(const std::tuple& lhs, const std::tuple& rhs) { ++ return mock_compare_arg(std::get(lhs), std::get(rhs)) ? 0 : 1; ++} ++ ++template ++typename std::enable_if<1 < I, int>::type ++mock_compare_tuple(const std::tuple& lhs, const std::tuple& rhs) { ++ auto res = mock_compare_tuple(lhs, rhs); ++ ++ if (res != 0) ++ return res; ++ ++ return mock_compare_arg(std::get(lhs), std::get(rhs)) ? 0 : I; ++} ++ ++//template ::value, int>::type = 0> ++template ++struct mock_compare_map { ++ typedef std::map values_type; ++ ++ constexpr static T* begin_pointer = reinterpret_cast(0x1000); ++ constexpr static T* end_pointer = reinterpret_cast(0x2000); ++ ++ static bool is_key(const T* k) { ++ return k >= begin_pointer && k < end_pointer; ++ } ++ ++ static bool has_key(const T* k) { ++ return values.find(k) != values.end(); ++ } ++ ++ static bool has_value(const T* v) { ++ return std::find_if(values.begin(), values.end(), [v](typename values_type::value_type& kv) { return v == kv.second; }) != values.end(); ++ } ++ ++ static const T* get(const T* k) { ++ auto itr = values.find(k); ++ CPPUNIT_ASSERT_MESSAGE("mock_compare_map get failed, not inserted", itr != values.end()); ++ return itr->second; ++ } ++ ++ static values_type values; ++}; ++ ++template ++typename mock_compare_map::values_type mock_compare_map::values; ++ ++template ++void mock_compare_add(T* v) { ++ mock_compare_map::add_value(v); ++} ++ ++// ++// Specialize: ++// ++ ++template <> ++inline bool mock_compare_arg(sockaddr* lhs, sockaddr* rhs) { ++ return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs); ++} ++template <> ++inline bool mock_compare_arg(const sockaddr* lhs, const sockaddr* rhs) { ++ return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs); ++} ++ ++template <> ++inline bool mock_compare_arg(torrent::Event* lhs, torrent::Event* rhs) { ++ if (mock_compare_map::is_key(lhs)) { ++ if (!mock_compare_map::has_value(rhs)) { ++ mock_compare_map::values[lhs] = rhs; ++ return true; ++ } ++ ++ return mock_compare_map::has_key(lhs) && mock_compare_map::get(lhs) == rhs; ++ } ++ ++ return lhs == rhs; ++} ++ ++#endif +diff --git a/test/helpers/mock_function.cc b/test/helpers/mock_function.cc +new file mode 100644 +index 00000000..83e81551 +--- /dev/null ++++ b/test/helpers/mock_function.cc +@@ -0,0 +1,170 @@ ++#include "config.h" ++ ++#include "mock_function.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MOCK_CLEANUP_MAP(MOCK_FUNC) \ ++ CPPUNIT_ASSERT_MESSAGE("expected mock function calls not completed for '" #MOCK_FUNC "'", mock_cleanup_map(&MOCK_FUNC) || ignore_assert); ++#define MOCK_LOG(log_fmt, ...) \ ++ lt_log_print(torrent::LOG_MOCK_CALLS, "%s: " log_fmt, __func__, __VA_ARGS__); ++ ++void ++mock_clear(bool ignore_assert) { ++ MOCK_CLEANUP_MAP(torrent::fd__accept); ++ MOCK_CLEANUP_MAP(torrent::fd__bind); ++ MOCK_CLEANUP_MAP(torrent::fd__close); ++ MOCK_CLEANUP_MAP(torrent::fd__connect); ++ MOCK_CLEANUP_MAP(torrent::fd__fcntl_int); ++ MOCK_CLEANUP_MAP(torrent::fd__listen); ++ MOCK_CLEANUP_MAP(torrent::fd__setsockopt_int); ++ MOCK_CLEANUP_MAP(torrent::fd__socket); ++ ++ MOCK_CLEANUP_MAP(torrent::poll_event_open); ++ MOCK_CLEANUP_MAP(torrent::poll_event_close); ++ MOCK_CLEANUP_MAP(torrent::poll_event_closed); ++ MOCK_CLEANUP_MAP(torrent::poll_event_insert_read); ++ MOCK_CLEANUP_MAP(torrent::poll_event_insert_write); ++ MOCK_CLEANUP_MAP(torrent::poll_event_insert_error); ++ MOCK_CLEANUP_MAP(torrent::poll_event_remove_read); ++ MOCK_CLEANUP_MAP(torrent::poll_event_remove_write); ++ MOCK_CLEANUP_MAP(torrent::poll_event_remove_error); ++ ++ MOCK_CLEANUP_MAP(torrent::random_uniform_uint16); ++ MOCK_CLEANUP_MAP(torrent::random_uniform_uint32); ++ ++ mock_compare_map::values.clear(); ++}; ++ ++void mock_init() { ++ log_add_group_output(torrent::LOG_MOCK_CALLS, "test_output"); ++ mock_clear(true); ++} ++ ++void mock_cleanup() { ++ mock_clear(false); ++} ++ ++namespace torrent { ++ ++// ++// Mock functions for 'torrent/net/fd.h': ++// ++ ++int fd__accept(int socket, sockaddr *address, socklen_t *address_len) { ++ MOCK_LOG("entry socket:%i address:%s address_len:%u", ++ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len)); ++ auto ret = mock_call(__func__, &torrent::fd__accept, socket, address, address_len); ++ MOCK_LOG("exit socket:%i address:%s address_len:%u", ++ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len)); ++ return ret; ++} ++ ++int fd__bind(int socket, const sockaddr *address, socklen_t address_len) { ++ MOCK_LOG("socket:%i address:%s address_len:%u", ++ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len); ++ return mock_call(__func__, &torrent::fd__bind, socket, address, address_len); ++} ++ ++int fd__close(int fildes) { ++ MOCK_LOG("filedes:%i", fildes); ++ return mock_call(__func__, &torrent::fd__close, fildes); ++} ++ ++int fd__connect(int socket, const sockaddr *address, socklen_t address_len) { ++ MOCK_LOG("socket:%i address:%s address_len:%u", ++ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len); ++ return mock_call(__func__, &torrent::fd__connect, socket, address, address_len); ++} ++ ++int fd__fcntl_int(int fildes, int cmd, int arg) { ++ MOCK_LOG("filedes:%i cmd:%i arg:%i", fildes, cmd, arg); ++ return mock_call(__func__, &torrent::fd__fcntl_int, fildes, cmd, arg); ++} ++ ++int fd__listen(int socket, int backlog) { ++ MOCK_LOG("socket:%i backlog:%i", socket, backlog); ++ return mock_call(__func__, &torrent::fd__listen, socket, backlog); ++} ++ ++int fd__setsockopt_int(int socket, int level, int option_name, int option_value) { ++ MOCK_LOG("socket:%i level:%i option_name:%i option_value:%i", ++ socket, level, option_name, option_value); ++ return mock_call(__func__, &torrent::fd__setsockopt_int, socket, level, option_name, option_value); ++} ++ ++int fd__socket(int domain, int type, int protocol) { ++ MOCK_LOG("domain:%i type:%i protocol:%i", domain, type, protocol); ++ return mock_call(__func__, &torrent::fd__socket, domain, type, protocol); ++} ++ ++// ++// Mock functions for 'torrent/event.h': ++// ++ ++void poll_event_open(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_open, event); ++} ++ ++void poll_event_close(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_close, event); ++} ++ ++void poll_event_closed(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_closed, event); ++} ++ ++void poll_event_insert_read(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_insert_read, event); ++} ++ ++void poll_event_insert_write(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_insert_write, event); ++} ++ ++void poll_event_insert_error(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_insert_error, event); ++} ++ ++void poll_event_remove_read(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_remove_read, event); ++} ++ ++void poll_event_remove_write(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_remove_write, event); ++} ++ ++void poll_event_remove_error(Event* event) { ++ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name()); ++ return mock_call(__func__, &torrent::poll_event_remove_error, event); ++} ++ ++// ++// Mock functions for 'torrent/utils/random.h': ++// ++ ++uint16_t random_uniform_uint16(uint16_t min, uint16_t max) { ++ MOCK_LOG("min:%" PRIu16 " max:%" PRIu16, min, max); ++ return mock_call(__func__, &torrent::random_uniform_uint16, min, max); ++} ++ ++uint32_t random_uniform_uint32(uint32_t min, uint32_t max) { ++ MOCK_LOG("min:%" PRIu32 " max:%" PRIu32, min, max); ++ return mock_call(__func__, &torrent::random_uniform_uint32, min, max); ++} ++ ++} +diff --git a/test/helpers/mock_function.h b/test/helpers/mock_function.h +new file mode 100644 +index 00000000..6c194137 +--- /dev/null ++++ b/test/helpers/mock_function.h +@@ -0,0 +1,133 @@ ++#ifndef LIBTORRENT_HELPERS_MOCK_FUNCTION_H ++#define LIBTORRENT_HELPERS_MOCK_FUNCTION_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "helpers/mock_compare.h" ++ ++template ++struct mock_function_map { ++ typedef std::tuple call_type; ++ typedef std::vector call_list_type; ++ typedef std::map func_map_type; ++ ++ typedef std::function function_type; ++ typedef std::map redirect_map_type; ++ ++ static func_map_type functions; ++ static redirect_map_type redirects; ++ ++ static bool cleanup(void* fn) { ++ redirects.erase(fn); ++ return functions.erase(fn) == 0; ++ } ++ ++ static R ret_erase(void* fn) { ++ auto itr = functions.find(fn); ++ auto ret = std::get<0>(itr->second.front()); ++ itr->second.erase(itr->second.begin()); ++ ++ if (itr->second.empty()) ++ functions.erase(itr); ++ ++ return ret; ++ } ++}; ++ ++template ++typename mock_function_map::func_map_type mock_function_map::functions; ++template ++typename mock_function_map::redirect_map_type mock_function_map::redirects; ++ ++struct mock_void {}; ++ ++template ++struct mock_function_type { ++ typedef mock_function_map type; ++ ++ static int compare_expected(typename type::call_type lhs, Args... rhs) { ++ return mock_compare_tuple(lhs, std::make_tuple(rhs...)); ++ } ++ ++ static R ret_erase(void* fn) { return type::ret_erase(fn); } ++ static bool has_redirect(void* fn) { return type::redirects.find(fn) != type::redirects.end(); } ++ static R call_redirect(void* fn, Args... args) { return type::redirects.find(fn)->second(args...); } ++}; ++ ++template ++struct mock_function_type { ++ typedef mock_function_map type; ++ ++ static int compare_expected(typename type::call_type lhs, Args... rhs) { ++ return mock_compare_tuple(lhs, std::make_tuple(rhs...)); ++ } ++ ++ static void ret_erase(void* fn) { type::ret_erase(fn); } ++ static bool has_redirect(void* fn) { return type::redirects.find(fn) != type::redirects.end(); } ++ static void call_redirect(void* fn, Args... args) { type::redirects.find(fn)->second(args...); } ++}; ++ ++void mock_init(); ++void mock_cleanup(); ++ ++template ++bool ++mock_cleanup_map(R fn[[gnu::unused]](Args...)) { ++ return mock_function_type::type::cleanup(reinterpret_cast(fn)); ++} ++ ++template ++void ++mock_expect(R fn(Args...), R ret, Args... args) { ++ typedef mock_function_map mock_map; ++ mock_map::functions[reinterpret_cast(fn)].push_back(std::tuple(ret, args...)); ++} ++ ++template ++void ++mock_expect(void fn(Args...), Args... args) { ++ typedef mock_function_map mock_map; ++ mock_map::functions[reinterpret_cast(fn)].push_back(std::tuple(mock_void(), args...)); ++} ++ ++template ++void ++mock_redirect(R fn(Args...), std::function func) { ++ typedef mock_function_map mock_map; ++ mock_map::redirects[reinterpret_cast(fn)] = func; ++} ++ ++template ++auto ++mock_call_direct(std::string name, R fn(Args...), Args... args) -> decltype(fn(args...)) { ++ typedef mock_function_type mock_type; ++ ++ auto itr = mock_type::type::functions.find(reinterpret_cast(fn)); ++ CPPUNIT_ASSERT_MESSAGE(("mock_call expected function calls exhausted by '" + name + "'").c_str(), ++ itr != mock_type::type::functions.end()); ++ ++ auto mismatch_arg = mock_type::compare_expected(itr->second.front(), args...); ++ CPPUNIT_ASSERT_MESSAGE(("mock_call expected function call argument " + std::to_string(mismatch_arg) + " mismatch for '" + name + "'").c_str(), ++ mismatch_arg == 0); ++ ++ return mock_type::ret_erase(reinterpret_cast(fn)); ++} ++ ++template ++auto ++mock_call(std::string name, R fn(Args...), Args... args) -> decltype(fn(args...)) { ++ typedef mock_function_type mock_type; ++ ++ if (mock_type::has_redirect(reinterpret_cast(fn))) ++ return mock_type::call_redirect(reinterpret_cast(fn), args...); ++ ++ return mock_call_direct(name, fn, args...); ++} ++ ++#endif +diff --git a/test/helpers/network.h b/test/helpers/network.h +new file mode 100644 +index 00000000..6cf2f870 +--- /dev/null ++++ b/test/helpers/network.h +@@ -0,0 +1,182 @@ ++#ifndef LIBTORRENT_HELPER_NETWORK_H ++#define LIBTORRENT_HELPER_NETWORK_H ++ ++#include ++#include ++#include ++ ++#include "torrent/net/address_info.h" ++ ++// ++// Socket addresses ++// ++ ++#define TEST_DEFAULT_SA \ ++ auto sin_any = wrap_ai_get_first_sa("0.0.0.0"); \ ++ auto sin_any_5000 = wrap_ai_get_first_sa("0.0.0.0", "5000"); \ ++ auto sin_any_5005 = wrap_ai_get_first_sa("0.0.0.0", "5005"); \ ++ auto sin_bc = wrap_ai_get_first_sa("255.255.255.255"); \ ++ auto sin_bc_5000 = wrap_ai_get_first_sa("255.255.255.255", "5000"); \ ++ auto sin_bnd = wrap_ai_get_first_sa("123.123.123.123"); \ ++ auto sin_1 = wrap_ai_get_first_sa("1.2.3.4"); \ ++ auto sin_1_5000 = wrap_ai_get_first_sa("1.2.3.4", "5000"); \ ++ auto sin_1_5005 = wrap_ai_get_first_sa("1.2.3.4", "5005"); \ ++ auto sin_1_5100 = wrap_ai_get_first_sa("1.2.3.4", "5100"); \ ++ auto sin_2 = wrap_ai_get_first_sa("4.3.2.1"); \ ++ auto sin_2_5000 = wrap_ai_get_first_sa("4.3.2.1", "5000"); \ ++ auto sin_2_5100 = wrap_ai_get_first_sa("4.3.2.1", "5100"); \ ++ \ ++ auto sin6_any = wrap_ai_get_first_sa("::"); \ ++ auto sin6_any_5000 = wrap_ai_get_first_sa("::", "5000"); \ ++ auto sin6_any_5005 = wrap_ai_get_first_sa("::", "5005"); \ ++ auto sin6_bnd = wrap_ai_get_first_sa("ff01::123"); \ ++ auto sin6_1 = wrap_ai_get_first_sa("ff01::1"); \ ++ auto sin6_1_5000 = wrap_ai_get_first_sa("ff01::1", "5000"); \ ++ auto sin6_1_5005 = wrap_ai_get_first_sa("ff01::1", "5005"); \ ++ auto sin6_1_5100 = wrap_ai_get_first_sa("ff01::1", "5100"); \ ++ auto sin6_2 = wrap_ai_get_first_sa("ff02::2"); \ ++ auto sin6_2_5000 = wrap_ai_get_first_sa("ff02::2", "5000"); \ ++ auto sin6_2_5100 = wrap_ai_get_first_sa("ff02::2", "5100"); \ ++ auto sin6_v4_1 = wrap_ai_get_first_sa("::ffff:1.2.3.4"); \ ++ auto sin6_v4_1_5000 = wrap_ai_get_first_sa("::ffff:1.2.3.4", "5000"); \ ++ auto sin6_v4_any = wrap_ai_get_first_sa("::ffff:0.0.0.0"); \ ++ auto sin6_v4_any_5000 = wrap_ai_get_first_sa("::ffff:0.0.0.0", "5000"); \ ++ auto sin6_v4_bc = wrap_ai_get_first_sa("::ffff:255.255.255.255"); \ ++ auto sin6_v4_bc_5000 = wrap_ai_get_first_sa("::ffff:255.255.255.255", "5000"); \ ++ auto sin6_v4_bnd = wrap_ai_get_first_sa("::ffff:123.123.123.123"); \ ++ \ ++ auto c_sin_any = wrap_ai_get_first_c_sa("0.0.0.0"); \ ++ auto c_sin_any_5000 = wrap_ai_get_first_c_sa("0.0.0.0", "5000"); \ ++ auto c_sin_any_5005 = wrap_ai_get_first_c_sa("0.0.0.0", "5005"); \ ++ auto c_sin_any_5010 = wrap_ai_get_first_c_sa("0.0.0.0", "5010"); \ ++ auto c_sin_any_6881 = wrap_ai_get_first_c_sa("0.0.0.0", "6881"); \ ++ auto c_sin_any_6900 = wrap_ai_get_first_c_sa("0.0.0.0", "6900"); \ ++ auto c_sin_any_6999 = wrap_ai_get_first_c_sa("0.0.0.0", "6999"); \ ++ auto c_sin_bc = wrap_ai_get_first_c_sa("255.255.255.255"); \ ++ auto c_sin_bc_5000 = wrap_ai_get_first_c_sa("255.255.255.255", "5000"); \ ++ auto c_sin_bnd = wrap_ai_get_first_c_sa("123.123.123.123"); \ ++ auto c_sin_bnd_5000 = wrap_ai_get_first_c_sa("123.123.123.123", "5000"); \ ++ auto c_sin_bnd_6881 = wrap_ai_get_first_c_sa("123.123.123.123", "6881"); \ ++ auto c_sin_bnd_6900 = wrap_ai_get_first_c_sa("123.123.123.123", "6900"); \ ++ auto c_sin_bnd_6999 = wrap_ai_get_first_c_sa("123.123.123.123", "6999"); \ ++ auto c_sin_1 = wrap_ai_get_first_c_sa("1.2.3.4"); \ ++ auto c_sin_1_5000 = wrap_ai_get_first_c_sa("1.2.3.4", "5000"); \ ++ auto c_sin_1_5005 = wrap_ai_get_first_c_sa("1.2.3.4", "5005"); \ ++ auto c_sin_1_5010 = wrap_ai_get_first_c_sa("1.2.3.4", "5010"); \ ++ auto c_sin_1_6881 = wrap_ai_get_first_c_sa("1.2.3.4", "6881"); \ ++ auto c_sin_1_6900 = wrap_ai_get_first_c_sa("1.2.3.4", "6900"); \ ++ auto c_sin_1_6999 = wrap_ai_get_first_c_sa("1.2.3.4", "6999"); \ ++ auto c_sin_2 = wrap_ai_get_first_c_sa("4.3.2.1"); \ ++ auto c_sin_2_5000 = wrap_ai_get_first_c_sa("4.3.2.1", "5000"); \ ++ auto c_sin_2_5100 = wrap_ai_get_first_c_sa("4.3.2.1", "5100"); \ ++ \ ++ auto c_sin6_any = wrap_ai_get_first_c_sa("::"); \ ++ auto c_sin6_any_5000 = wrap_ai_get_first_c_sa("::", "5000"); \ ++ auto c_sin6_any_5005 = wrap_ai_get_first_c_sa("::", "5005"); \ ++ auto c_sin6_any_5010 = wrap_ai_get_first_c_sa("::", "5010"); \ ++ auto c_sin6_any_6881 = wrap_ai_get_first_c_sa("::", "6881"); \ ++ auto c_sin6_any_6900 = wrap_ai_get_first_c_sa("::", "6900"); \ ++ auto c_sin6_any_6999 = wrap_ai_get_first_c_sa("::", "6999"); \ ++ auto c_sin6_bnd = wrap_ai_get_first_c_sa("ff01::123"); \ ++ auto c_sin6_bnd_5000 = wrap_ai_get_first_c_sa("ff01::123", "5000"); \ ++ auto c_sin6_bnd_6881 = wrap_ai_get_first_c_sa("ff01::123", "6881"); \ ++ auto c_sin6_bnd_6900 = wrap_ai_get_first_c_sa("ff01::123", "6900"); \ ++ auto c_sin6_bnd_6999 = wrap_ai_get_first_c_sa("ff01::123", "6999"); \ ++ auto c_sin6_v4_1_5000 = wrap_ai_get_first_c_sa("::ffff:1.2.3.4", "5000"); \ ++ auto c_sin6_1 = wrap_ai_get_first_c_sa("ff01::1"); \ ++ auto c_sin6_1_5000 = wrap_ai_get_first_c_sa("ff01::1", "5000"); \ ++ auto c_sin6_1_5005 = wrap_ai_get_first_c_sa("ff01::1", "5005"); \ ++ auto c_sin6_1_5010 = wrap_ai_get_first_c_sa("ff01::1", "5010"); \ ++ auto c_sin6_1_5100 = wrap_ai_get_first_c_sa("ff01::1", "5100"); \ ++ auto c_sin6_1_6881 = wrap_ai_get_first_c_sa("ff01::1", "6881"); \ ++ auto c_sin6_1_6900 = wrap_ai_get_first_c_sa("ff01::1", "6900"); \ ++ auto c_sin6_1_6999 = wrap_ai_get_first_c_sa("ff01::1", "6999"); \ ++ auto c_sin6_2 = wrap_ai_get_first_c_sa("ff02::2"); \ ++ auto c_sin6_2_5000 = wrap_ai_get_first_c_sa("ff02::2", "5000"); \ ++ auto c_sin6_2_5100 = wrap_ai_get_first_c_sa("ff02::2", "5100"); ++ ++inline bool ++compare_sin6_addr(in6_addr lhs, in6_addr rhs) { ++ return std::equal(lhs.s6_addr, lhs.s6_addr + 16, rhs.s6_addr); ++} ++ ++inline bool ++compare_listen_result(const torrent::listen_result_type& lhs, int rhs_fd, const torrent::c_sa_unique_ptr& rhs_sap) { ++ return lhs.fd == rhs_fd && ++ ((lhs.address && rhs_sap) || ((lhs.address && rhs_sap) && torrent::sap_equal(lhs.address, rhs_sap))); ++} ++ ++inline torrent::sa_unique_ptr ++wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) { ++ auto sa = torrent::ai_get_first_sa(nodename, servname, hints); ++ ++ CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(), ++ sa != nullptr); ++ return sa; ++} ++ ++inline torrent::c_sa_unique_ptr ++wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) { ++ auto sa = torrent::ai_get_first_sa(nodename, servname, hints); ++ ++ CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(), ++ sa != nullptr); ++ return torrent::c_sa_unique_ptr(sa.release()); ++} ++ ++// ++// Address info tests: ++// ++ ++typedef std::function test_ai_ref; ++ ++enum ai_flags_enum : int { ++ aif_none = 0x0, ++ aif_inet = 0x1, ++ aif_inet6 = 0x2, ++ aif_any = 0x4, ++}; ++ ++constexpr ai_flags_enum operator | (ai_flags_enum a, ai_flags_enum b) { ++ return static_cast(static_cast(a) | static_cast(b)); ++} ++ ++template ++inline bool ++test_valid_ai_ref(test_ai_ref ftor, uint16_t port = 0) { ++ torrent::ai_unique_ptr ai; ++ ++ if (int err = ftor(ai)) { ++ std::cout << std::endl << "valid_ai_ref got error '" << gai_strerror(err) << "'" << std::endl; ++ return false; ++ } ++ ++ if ((ai_flags & aif_inet) && !torrent::sa_is_inet(ai->ai_addr)) ++ return false; ++ ++ if ((ai_flags & aif_inet6) && !torrent::sa_is_inet6(ai->ai_addr)) ++ return false; ++ ++ if (!!(ai_flags & aif_any) == !torrent::sa_is_any(ai->ai_addr)) ++ return false; ++ ++ if (torrent::sa_port(ai->ai_addr) != port) ++ return false; ++ ++ return true; ++} ++ ++inline bool ++test_valid_ai_ref_err(test_ai_ref ftor, int expect_err) { ++ torrent::ai_unique_ptr ai; ++ int err = ftor(ai); ++ ++ if (err != expect_err) { ++ std::cout << std::endl << "ai_ref_err got wrong error, expected '" << gai_strerror(expect_err) << "', got '" << gai_strerror(err) << "'" << std::endl; ++ return false; ++ } ++ ++ return true; ++} ++ ++#endif +diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc +new file mode 100644 +index 00000000..02803ffc +--- /dev/null ++++ b/test/helpers/progress_listener.cc +@@ -0,0 +1,63 @@ ++#include "config.h" ++ ++#include "progress_listener.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include "torrent/utils/log.h" ++#include "torrent/utils/log_buffer.h" ++ ++static std::string ++get_test_path(const test_list_type& tl) { ++ if (tl.size() < 2) ++ return ""; ++ ++ return std::accumulate(std::next(tl.begin()), std::prev(tl.end()), std::string(), [](std::string result, CppUnit::Test* test) { ++ return std::move(result) + test->getName() + "::"; ++ }); ++} ++ ++void ++progress_listener::startTest(CppUnit::Test *test) { ++ std::cout << get_test_path(m_test_path) << test->getName() << std::flush; ++ ++ torrent::log_cleanup(); ++ ++ m_last_test_failed = false; ++ m_current_log_buffer = torrent::log_open_log_buffer("test_output"); ++} ++ ++void ++progress_listener::addFailure(const CppUnit::TestFailure &failure) { ++ // AddFailure is called for parent test suits, so only deal with leafs. ++ if (m_current_log_buffer == nullptr) ++ return; ++ ++ std::cout << " : " << (failure.isError() ? "error" : "assertion"); ++ ++ m_last_test_failed = true; ++ m_failures.push_back(std::move(failure_type{failure.failedTestName(), std::move(m_current_log_buffer)})); ++} ++ ++void ++progress_listener::endTest(CppUnit::Test *test) { ++ std::cout << (m_last_test_failed ? "" : " : OK") << std::endl; ++ ++ m_current_log_buffer.reset(); ++ torrent::log_cleanup(); ++} ++ ++void ++progress_listener::startSuite(CppUnit::Test *suite) { ++ m_test_path.push_back(suite); ++ ++ std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl; ++} ++ ++void ++progress_listener::endSuite(CppUnit::Test *suite) { ++ m_test_path.pop_back(); ++} +diff --git a/test/helpers/progress_listener.h b/test/helpers/progress_listener.h +new file mode 100644 +index 00000000..18fb8faa +--- /dev/null ++++ b/test/helpers/progress_listener.h +@@ -0,0 +1,47 @@ ++#include ++#include ++#include ++#include ++#include ++ ++#include "torrent/utils/log_buffer.h" ++ ++struct failure_type { ++ std::string name; ++ torrent::log_buffer_ptr log; ++}; ++ ++typedef std::unique_ptr test_failure_ptr; ++typedef std::vector test_list_type; ++typedef std::vector failure_list_type; ++ ++class progress_listener : public CppUnit::TestListener { ++public: ++ progress_listener() : m_last_test_failed(false) {} ++ ++ void startTest(CppUnit::Test *test) override; ++ void addFailure(const CppUnit::TestFailure &failure) override; ++ void endTest(CppUnit::Test *test) override; ++ ++ void startSuite(CppUnit::Test *suite) override; ++ void endSuite(CppUnit::Test *suite) override; ++ ++ //Called by a TestRunner before running the test. ++ // void startTestRun(CppUnit::Test *test, CppUnit::TestResult *event_manager) override; ++ ++ // Called by a TestRunner after running the test. ++ // void endTestRun(CppUnit::Test *test, CppUnit::TestResult *event_manager) override; ++ ++ const failure_list_type& failures() { return m_failures; } ++ failure_list_type&& move_failures() { return std::move(m_failures); } ++ ++private: ++ progress_listener(const progress_listener& rhs) = delete; ++ void operator =(const progress_listener& rhs) = delete; ++ ++ test_list_type m_test_path; ++ failure_list_type m_failures; ++ bool m_last_test_failed; ++ ++ torrent::log_buffer_ptr m_current_log_buffer; ++}; +diff --git a/test/helpers/test_fixture.cc b/test/helpers/test_fixture.cc +new file mode 100644 +index 00000000..4d8d7214 +--- /dev/null ++++ b/test/helpers/test_fixture.cc +@@ -0,0 +1,18 @@ ++#include "config.h" ++ ++#include "test_fixture.h" ++ ++#include "torrent/utils/log.h" ++ ++void ++test_fixture::setUp() { ++ mock_init(); ++ ++ log_add_group_output(torrent::LOG_CONNECTION_BIND, "test_output"); ++ log_add_group_output(torrent::LOG_CONNECTION_FD, "test_output"); ++} ++ ++void ++test_fixture::tearDown() { ++ mock_cleanup(); ++} +diff --git a/test/helpers/test_fixture.h b/test/helpers/test_fixture.h +new file mode 100644 +index 00000000..312d5009 +--- /dev/null ++++ b/test/helpers/test_fixture.h +@@ -0,0 +1,14 @@ ++#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H ++#define LIBTORRENT_HELPER_TEST_FIXTURE_H ++ ++#include ++ ++#include "helpers/mock_function.h" ++ ++class test_fixture : public CppUnit::TestFixture { ++public: ++ void setUp(); ++ void tearDown(); ++}; ++ ++#endif +diff --git a/test/helpers/utils.h b/test/helpers/utils.h +new file mode 100644 +index 00000000..d18450c1 +--- /dev/null ++++ b/test/helpers/utils.h +@@ -0,0 +1,60 @@ ++#ifndef LIBTORRENT_HELPER_UTILS_H ++#define LIBTORRENT_HELPER_UTILS_H ++ ++#include ++#include ++#include ++#include ++ ++static void ++dump_failure_log(const failure_type& failure) { ++ if (failure.log->empty()) ++ return; ++ ++ std::cout << std::endl << failure.name << std::endl; ++ ++ // Doesn't print dump messages as log_buffer drops them. ++ std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) { ++ std::cout << entry.timestamp << ' ' << entry.message << '\n'; ++ }); ++ ++ std::cout << std::flush; ++} ++ ++static void ++dump_failures(const failure_list_type& failures) { ++ if (failures.empty()) ++ return; ++ ++ std::cout << std::endl ++ << "=================" << std::endl ++ << "Failed Test Logs:" << std::endl ++ << "=================" << std::endl; ++ ++ std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) { ++ dump_failure_log(failure); ++ }); ++ std::cout << std::endl; ++} ++ ++static ++void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) { ++ if (c_test_names == NULL || std::string(c_test_names).empty()) { ++ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); ++ return; ++ } ++ ++ const std::string& test_names(c_test_names); ++ ++ size_t pos = 0; ++ size_t next = 0; ++ ++ while ((next = test_names.find(',', pos)) < test_names.size()) { ++ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest()); ++ pos = next + 1; ++ } ++ ++ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest()); ++} ++ ++#endif +diff --git a/test/main.cc b/test/main.cc +index e69d3d70..da93fead 100644 +--- a/test/main.cc ++++ b/test/main.cc +@@ -1,44 +1,92 @@ ++#include "config.h" ++ ++#include + #include ++#include ++#include + #include + #include + #include + #include ++#include + #include + #include + +-int main(int argc, char* argv[]) +-{ ++#ifdef USE_EXECINFO ++#include ++#endif ++ ++#include "helpers/progress_listener.h" ++#include "helpers/utils.h" ++ ++CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net"); ++CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/net"); ++CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/utils"); ++ ++void ++do_test_panic(int signum) { ++ signal(signum, SIG_DFL); ++ ++ std::cout << std::endl << std::endl << "Caught " << strsignal(signum) << ", dumping stack:" << std::endl << std::endl; ++ ++#ifdef USE_EXECINFO ++ void* stackPtrs[20]; ++ ++ // Print the stack and exit. ++ int stackSize = backtrace(stackPtrs, 20); ++ char** stackStrings = backtrace_symbols(stackPtrs, stackSize); ++ ++ for (int i = 0; i < stackSize; ++i) ++ std::cout << stackStrings[i] << std::endl; ++ ++#else ++ std::cout << "Stack dump not enabled." << std::endl; ++#endif ++ ++ std::cout << std::endl; ++ torrent::log_cleanup(); ++ std::abort(); ++} ++ ++void ++register_signal_handlers() { ++ struct sigaction sa; ++ sigemptyset(&sa.sa_mask); ++ sa.sa_flags = SA_RESTART; ++ sa.sa_handler = &do_test_panic; ++ ++ if (sigaction(SIGSEGV, &sa, NULL) == -1) { ++ std::cout << "Could not register signal handlers." << std::endl; ++ exit(-1); ++ } ++} ++ ++int main(int argc, char* argv[]) { ++ register_signal_handlers(); ++ + CppUnit::TestResult controller; + CppUnit::TestResultCollector result; +- CppUnit::BriefTestProgressListener progressListener; ++ progress_listener progress; + + controller.addListener( &result ); +- controller.addListener( &progressListener ); +- +- // Get the top level suite from the registry +- CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest(); ++ controller.addListener( &progress ); + +- // Adds the test to the list of test to run + CppUnit::TextUi::TestRunner runner; +- runner.addTest( suite ); ++ add_tests(runner, std::getenv("TEST_NAME")); + +- // Change the default outputter to a compiler error format outputter +- runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), +- std::cerr ) ); + try { + std::cout << "Running "; + runner.run( controller ); + +- std::cerr << std::endl; +- ++ // TODO: Make outputter. ++ dump_failures(progress.failures()); ++ + // Print test in a compiler compatible format. + CppUnit::CompilerOutputter outputter( &result, std::cerr ); + outputter.write(); + + } catch ( std::invalid_argument &e ) { // Test path not resolved +- std::cerr << std::endl +- << "ERROR: " << e.what() +- << std::endl; ++ std::cerr << std::endl << "ERROR: " << e.what() << std::endl; + return 1; + } + +diff --git a/test/net/test_socket_listen.cc b/test/net/test_socket_listen.cc +new file mode 100644 +index 00000000..e86a078b +--- /dev/null ++++ b/test/net/test_socket_listen.cc +@@ -0,0 +1,398 @@ ++#include "config.h" ++ ++#include "test_socket_listen.h" ++ ++#include "helpers/expect_fd.h" ++#include "helpers/expect_utils.h" ++#include "helpers/mock_function.h" ++#include "helpers/network.h" ++ ++#include ++#include ++#include ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_socket_listen, "net"); ++ ++struct test_sl_deleter { ++ void operator()(torrent::socket_listen* sl) const { if (!sl->is_open()) delete sl; } ++}; ++ ++typedef std::unique_ptr test_sl_unique_ptr; ++ ++#define TEST_SL_BEGIN(name) \ ++ test_sl_unique_ptr sl(new torrent::socket_listen); \ ++ std::vector sap_cache; \ ++ lt_log_print(torrent::LOG_MOCK_CALLS, "sl_begin: %s", name); \ ++ TEST_DEFAULT_SA; ++ ++#define TEST_SL_ASSERT_OPEN(_sap_bind, _sap_result, _flags) \ ++ TEST_SL_ASSERT_OPEN_PORT(_sap_bind, _sap_result, 5000, 5009, 5005, _flags); \ ++ CPPUNIT_ASSERT(sl->socket_address_port() == 5005); ++ ++#define TEST_SL_ASSERT_OPEN_PORT(_sap_bind, _sap_result, _first_port, _last_port, _itr_port, _flags) \ ++ expect_event_open_re(0); \ ++ CPPUNIT_ASSERT(sl->open(_sap_bind, _first_port, _last_port, _itr_port, _flags)); \ ++ CPPUNIT_ASSERT(sl->is_open()); \ ++ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get())); ++ ++#define TEST_SL_ASSERT_OPEN_SEQUENTIAL(_sap_bind, _sap_result, _first_port, _last_port, _flags) \ ++ expect_event_open_re(0); \ ++ CPPUNIT_ASSERT(sl->open_sequential(_sap_bind, _first_port, _last_port, _flags)); \ ++ CPPUNIT_ASSERT(sl->is_open()); \ ++ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get())); ++ ++#define TEST_SL_ASSERT_OPEN_RANDOMIZE(_sap_bind, _sap_result, _first_port, _last_port, _flags) \ ++ expect_event_open_re(0); \ ++ CPPUNIT_ASSERT(sl->open_randomize(_sap_bind, _first_port, _last_port, _flags)); \ ++ CPPUNIT_ASSERT(sl->is_open()); \ ++ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get())); ++ ++#define TEST_SL_ASSERT_CLOSED() \ ++ CPPUNIT_ASSERT(!sl->is_open()); \ ++ CPPUNIT_ASSERT(sl->file_descriptor() == -1); \ ++ CPPUNIT_ASSERT(sl->socket_address() == nullptr); \ ++ CPPUNIT_ASSERT(sl->socket_address_port() == 0); ++ ++#define TEST_SL_CLOSE(_fd) \ ++ mock_expect(&torrent::fd__close, 0, _fd); \ ++ mock_expect(&torrent::poll_event_closed, (torrent::Event*)sl.get()); \ ++ CPPUNIT_ASSERT_NO_THROW(sl->close()); \ ++ TEST_SL_ASSERT_CLOSED(); ++ ++#define TEST_SL_MOCK_CLOSED_PORT_RANGE(_src_sap, _first_port, _last_port) \ ++ { uint16_t _port = _first_port; do { \ ++ sap_cache.push_back(torrent::sap_copy(_src_sap)); \ ++ torrent::sap_set_port(sap_cache.back(), _port); \ ++ mock_expect(&torrent::fd__bind, -1, 1000, \ ++ (const sockaddr*)sap_cache.back().get(), \ ++ (socklen_t)torrent::sap_length(sap_cache.back())); \ ++ } while (_port++ != _last_port); \ ++ } ++ ++void ++test_socket_listen::test_basic() { ++ TEST_SL_BEGIN("basic"); ++ TEST_SL_ASSERT_CLOSED(); ++ CPPUNIT_ASSERT(sl->backlog() == SOMAXCONN); ++ CPPUNIT_ASSERT(sl->type_name() == std::string("socket_listen")); ++} ++ ++void ++test_socket_listen::test_open_error() { ++ { TEST_SL_BEGIN("open twice"); ++ expect_fd_inet6_tcp_nonblock(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flag_stream), ++ torrent::internal_error); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin_any, stream, no v4only"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_any), 5000, 5009, 5005, torrent::fd_flag_stream), ++ torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++} ++ ++void ++test_socket_listen::test_open_sap() { ++ { TEST_SL_BEGIN("sin6_any, stream"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin_any, stream|v4only"); ++ expect_fd_inet_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin_1, stream|v4only"); ++ expect_fd_inet_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin_1_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin_1), c_sin_1_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream|v6only"); ++ expect_fd_inet6_tcp(1000); ++ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v6only); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_1, stream|v6only"); ++ expect_fd_inet6_tcp(1000); ++ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true); ++ expect_fd_bind_listen(1000, c_sin6_1_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_1), c_sin6_1_5005, torrent::fd_flag_stream | torrent::fd_flag_v6only); ++ TEST_SL_CLOSE(1000); ++ }; ++} ++ ++void ++test_socket_listen::test_open_sap_error() { ++ { TEST_SL_BEGIN("unspec"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sa_make_unspec(), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("unix"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sa_make_unix("test"), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin_any_5005"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_any_5005), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any_5005"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any_5005), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin_any"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_to_v4mapped(sin_any), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin_1, v4mapped"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_to_v4mapped(sin_1), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin_broadcast"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_bc), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++} ++ ++void ++test_socket_listen::test_open_flags() { ++ { TEST_SL_BEGIN("sin_any, stream|v4only|nonblock"); ++ expect_fd_inet_tcp_nonblock(1000); ++ expect_fd_bind_listen(1000, c_sin_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy_addr(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_nonblock); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream|nonblock"); ++ expect_fd_inet6_tcp_nonblock(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin_any, stream|v4only|reuse_address"); ++ expect_fd_inet_tcp(1000); ++ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true); ++ expect_fd_bind_listen(1000, c_sin_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy_addr(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_reuse_address); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream|reuse_address"); ++ expect_fd_inet6_tcp(1000); ++ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_reuse_address); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin_any, stream|v4only|nonblock|reuse_address"); ++ expect_fd_inet_tcp_nonblock(1000); ++ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true); ++ expect_fd_bind_listen(1000, c_sin_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy_addr(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_nonblock | torrent::fd_flag_reuse_address); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream|nonblock|reuse_address"); ++ expect_fd_inet6_tcp_nonblock_reuseaddr(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock | torrent::fd_flag_reuse_address); ++ TEST_SL_CLOSE(1000); ++ }; ++} ++ ++void ++test_socket_listen::test_open_flags_error() { ++ { TEST_SL_BEGIN("sin6_any, fd_flags(0)"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flags(0)), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, fd_flags(0xffff)"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flags(0xffff)), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++} ++ ++void ++test_socket_listen::test_open_port_single() { ++ { TEST_SL_BEGIN("sin6_any, stream"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5000); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5000, 5000, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin_any, stream"); ++ expect_fd_inet_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin_any_5000); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin_any), c_sin_any_5000, 5000, 5000, 5000, torrent::fd_flag_stream | torrent::fd_flag_v4only); ++ TEST_SL_CLOSE(1000); ++ }; ++} ++ ++void ++test_socket_listen::test_open_port_single_error() { ++ { TEST_SL_BEGIN("sin6_any, 0, 0, 0"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 0, 0, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, 1000, 0, 0"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 1000, 0, 0, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, 0, 1000, 0"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 1000, 0, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, 0, 0, 500"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 0, 500, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, 0, 1000, 500"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 1000, 500, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++} ++ ++void ++test_socket_listen::test_open_port_range() { ++ { TEST_SL_BEGIN("sin6_any, stream, first"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5000); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, 5000, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, from first to middle port"); ++ expect_fd_inet6_tcp(1000); ++ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5004); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5000, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, from first to last port"); ++ expect_fd_inet6_tcp(1000); ++ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5009); ++ expect_fd_bind_listen(1000, c_sin6_any_5010); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5000, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, middle"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5005, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, from middle to last port"); ++ expect_fd_inet6_tcp(1000); ++ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5005, 5009); ++ expect_fd_bind_listen(1000, c_sin6_any_5010); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5005, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, last"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5010); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5010, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, from last to first port"); ++ expect_fd_inet6_tcp(1000); ++ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5010, 5010); ++ expect_fd_bind_listen(1000, c_sin6_any_5000); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, 5010, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++ { TEST_SL_BEGIN("sin6_any, stream, from last to middle port"); ++ expect_fd_inet6_tcp(1000); ++ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5010, 5010); ++ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5004); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5010, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++} ++ ++void ++test_socket_listen::test_open_port_range_error() { ++ { TEST_SL_BEGIN("sin6_any, first > last"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 4999, 5000, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, first > itr"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5001, 5009, 5000, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, itr > last"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5010, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, min first > last"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 2, 1, 2, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, min first > itr"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 2, 1000, 1, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, min itr > last"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 1, 2, 3, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, max first > last"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xffff, 0xfffe, 0xffff, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, max first > itr"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xffff, 0xffff, 0xfffe, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++ { TEST_SL_BEGIN("sin6_any, max itr > last"); ++ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xfffe, 0xfffe, 0xffff, torrent::fd_flag_stream), torrent::internal_error); ++ TEST_SL_ASSERT_CLOSED(); ++ }; ++} ++ ++void ++test_socket_listen::test_open_sequential() { ++ { TEST_SL_BEGIN("sin6_any, stream"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5000); ++ TEST_SL_ASSERT_OPEN_SEQUENTIAL(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++} ++ ++void ++test_socket_listen::test_open_randomize() { ++ { TEST_SL_BEGIN("sin6_any, stream"); ++ expect_random_uniform_uint16(5005, 5000, 5010); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5005); ++ TEST_SL_ASSERT_OPEN_RANDOMIZE(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, torrent::fd_flag_stream); ++ TEST_SL_CLOSE(1000); ++ }; ++} ++ ++// deal with reuse error ++ ++void ++test_socket_listen::test_accept() { ++ { TEST_SL_BEGIN("sin6_any, stream"); ++ expect_fd_inet6_tcp(1000); ++ expect_fd_bind_listen(1000, c_sin6_any_5000); ++ TEST_SL_ASSERT_OPEN_SEQUENTIAL(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, torrent::fd_flag_stream); ++ ++ std::vector accepted_connections; ++ ++ sl->set_slot_accepted([&accepted_connections](int accept_fd, torrent::sa_unique_ptr sap) { ++ accepted_connections.push_back(torrent::fd_sap_tuple{accept_fd, std::move(sap)}); ++ }); ++ ++ // CPPUNIT_ASSERT(accepted_connections.size() > 0 && torrent::fd_sap_equal(accepted_connections[0], torrent::fd_sap_tuple{2000, torrent::sap_copy(sin6_1_5100)})); ++ ++ TEST_SL_CLOSE(1000); ++ }; ++} +diff --git a/test/net/test_socket_listen.h b/test/net/test_socket_listen.h +new file mode 100644 +index 00000000..5d06f7f3 +--- /dev/null ++++ b/test/net/test_socket_listen.h +@@ -0,0 +1,44 @@ ++#include "helpers/test_fixture.h" ++ ++class test_socket_listen : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_socket_listen); ++ ++ CPPUNIT_TEST(test_basic); ++ ++ CPPUNIT_TEST(test_open_error); ++ CPPUNIT_TEST(test_open_sap); ++ CPPUNIT_TEST(test_open_sap_error); ++ CPPUNIT_TEST(test_open_flags); ++ CPPUNIT_TEST(test_open_flags_error); ++ ++ CPPUNIT_TEST(test_open_port_single); ++ CPPUNIT_TEST(test_open_port_single_error); ++ CPPUNIT_TEST(test_open_port_range); ++ CPPUNIT_TEST(test_open_port_range_error); ++ ++ CPPUNIT_TEST(test_open_sequential); ++ CPPUNIT_TEST(test_open_randomize); ++ ++ CPPUNIT_TEST(test_accept); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void test_basic(); ++ ++ void test_open_error(); ++ void test_open_sap(); ++ void test_open_sap_error(); ++ void test_open_flags(); ++ void test_open_flags_error(); ++ ++ void test_open_port_single(); ++ void test_open_port_single_error(); ++ void test_open_port_range(); ++ void test_open_port_range_error(); ++ ++ void test_open_sequential(); ++ void test_open_randomize(); ++ ++ void test_accept(); ++}; +diff --git a/test/torrent/net/test_address_info.cc b/test/torrent/net/test_address_info.cc +new file mode 100644 +index 00000000..e3ee24d1 +--- /dev/null ++++ b/test/torrent/net/test_address_info.cc +@@ -0,0 +1,62 @@ ++#include "config.h" ++ ++#include "test_address_info.h" ++ ++#include "helpers/network.h" ++#include "torrent/net/address_info.h" ++#include "torrent/net/socket_address.h" ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_address_info, "torrent/net"); ++ ++void ++test_address_info::test_basic() { ++ CPPUNIT_ASSERT(test_valid_ai_ref (std::bind(torrent::ai_get_addrinfo, "0.0.0.0", nullptr, nullptr, std::placeholders::_1))); ++ CPPUNIT_ASSERT(test_valid_ai_ref(std::bind(torrent::ai_get_addrinfo, "::", nullptr, nullptr, std::placeholders::_1))); ++ ++ CPPUNIT_ASSERT(test_valid_ai_ref (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", nullptr, nullptr, std::placeholders::_1))); ++ CPPUNIT_ASSERT(test_valid_ai_ref(std::bind(torrent::ai_get_addrinfo, "ff01::1", nullptr, nullptr, std::placeholders::_1))); ++ CPPUNIT_ASSERT(test_valid_ai_ref(std::bind(torrent::ai_get_addrinfo, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", nullptr, nullptr, std::placeholders::_1))); ++ ++ CPPUNIT_ASSERT(test_valid_ai_ref (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", "22123", nullptr, std::placeholders::_1), 22123)); ++ CPPUNIT_ASSERT(test_valid_ai_ref(std::bind(torrent::ai_get_addrinfo, "2001:db8:a::", "22123", nullptr, std::placeholders::_1), 22123)); ++ ++ CPPUNIT_ASSERT(test_valid_ai_ref (std::bind(torrent::ai_get_addrinfo, "localhost", nullptr, nullptr, std::placeholders::_1))); ++ ++ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "1.1.1.300", nullptr, nullptr, std::placeholders::_1), EAI_NONAME)); ++ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "2001:db8:a::22123", nullptr, nullptr, std::placeholders::_1), EAI_NONAME)); ++} ++ ++void ++test_address_info::test_numericserv() { ++ CPPUNIT_ASSERT(test_valid_ai_ref (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", nullptr, torrent::ai_make_hint(AI_NUMERICHOST, 0, 0).get(), std::placeholders::_1))); ++ ++ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "localhost", nullptr, torrent::ai_make_hint(AI_NUMERICHOST, 0, 0).get(), std::placeholders::_1), EAI_NONAME)); ++} ++ ++void ++test_address_info::test_helpers() { ++ torrent::sin_unique_ptr sin_zero = torrent::sin_from_sa(wrap_ai_get_first_sa("0.0.0.0")); ++ CPPUNIT_ASSERT(sin_zero != nullptr); ++ CPPUNIT_ASSERT(sin_zero->sin_family == AF_INET); ++ CPPUNIT_ASSERT(sin_zero->sin_port == 0); ++ CPPUNIT_ASSERT(sin_zero->sin_addr.s_addr == in_addr().s_addr); ++ ++ torrent::sin_unique_ptr sin_1 = torrent::sin_from_sa(wrap_ai_get_first_sa("1.2.3.4")); ++ CPPUNIT_ASSERT(sin_1 != nullptr); ++ CPPUNIT_ASSERT(sin_1->sin_family == AF_INET); ++ CPPUNIT_ASSERT(sin_1->sin_port == 0); ++ CPPUNIT_ASSERT(sin_1->sin_addr.s_addr == htonl(0x01020304)); ++ ++ torrent::sin6_unique_ptr sin6_zero = torrent::sin6_from_sa(wrap_ai_get_first_sa("::")); ++ CPPUNIT_ASSERT(sin6_zero != nullptr); ++ CPPUNIT_ASSERT(sin6_zero->sin6_family == AF_INET6); ++ CPPUNIT_ASSERT(sin6_zero->sin6_port == 0); ++ CPPUNIT_ASSERT(compare_sin6_addr(sin6_zero->sin6_addr, in6_addr{0})); ++ ++ torrent::sin6_unique_ptr sin6_1 = torrent::sin6_from_sa(wrap_ai_get_first_sa("ff01::1")); ++ CPPUNIT_ASSERT(sin6_1 != nullptr); ++ CPPUNIT_ASSERT(sin6_1->sin6_family == AF_INET6); ++ CPPUNIT_ASSERT(sin6_1->sin6_port == 0); ++ CPPUNIT_ASSERT(compare_sin6_addr(sin6_1->sin6_addr, in6_addr{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1})); ++ CPPUNIT_ASSERT(!compare_sin6_addr(sin6_1->sin6_addr, in6_addr{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2})); ++} +diff --git a/test/torrent/net/test_address_info.h b/test/torrent/net/test_address_info.h +new file mode 100644 +index 00000000..c2ce9188 +--- /dev/null ++++ b/test/torrent/net/test_address_info.h +@@ -0,0 +1,19 @@ ++#include ++ ++class test_address_info : public CppUnit::TestFixture { ++ CPPUNIT_TEST_SUITE(test_address_info); ++ ++ CPPUNIT_TEST(test_basic); ++ CPPUNIT_TEST(test_numericserv); ++ CPPUNIT_TEST(test_helpers); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void setUp() {} ++ void tearDown() {} ++ ++ void test_basic(); ++ void test_numericserv(); ++ void test_helpers(); ++}; +diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc +new file mode 100644 +index 00000000..3cab0c5e +--- /dev/null ++++ b/test/torrent/net/test_fd.cc +@@ -0,0 +1,24 @@ ++#include "config.h" ++ ++#include "test_fd.h" ++ ++#include ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net"); ++ ++void ++test_fd::test_valid_flags() { ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only)); ++ ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only)); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); ++ ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags())); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all))); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all))); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132))); ++} +diff --git a/test/torrent/net/test_fd.h b/test/torrent/net/test_fd.h +new file mode 100644 +index 00000000..6ba718fc +--- /dev/null ++++ b/test/torrent/net/test_fd.h +@@ -0,0 +1,12 @@ ++#include "helpers/test_fixture.h" ++ ++class test_fd : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_fd); ++ ++ CPPUNIT_TEST(test_valid_flags); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void test_valid_flags(); ++}; +diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc +new file mode 100644 +index 00000000..8a1b0c8a +--- /dev/null ++++ b/test/torrent/net/test_socket_address.cc +@@ -0,0 +1,383 @@ ++#include "config.h" ++ ++#include "test_socket_address.h" ++ ++#include "helpers/network.h" ++#include "torrent/exceptions.h" ++#include "torrent/net/socket_address.h" ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_socket_address, "torrent/net"); ++ ++void ++test_socket_address::test_sa_is_any() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_is_any(sin_any)); ++ CPPUNIT_ASSERT(torrent::sap_is_any(sin_any_5000)); ++ CPPUNIT_ASSERT(torrent::sap_is_any(sin6_v4_any)); ++ CPPUNIT_ASSERT(torrent::sap_is_any(sin6_v4_any_5000)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_bc)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(sin6_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_bc_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_1_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(sin6_1_5000)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_bc)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin6_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_bc_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_1_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin6_1_5000)); ++} ++ ++void ++test_socket_address::test_sa_is_broadcast() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin_bc)); ++ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin_bc_5000)); ++ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin6_v4_bc)); ++ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin6_v4_bc_5000)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_any)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_any)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_any_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_1_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_any_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_1_5000)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_any)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_any)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_1)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_any_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_1_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_any_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_1_5000)); ++} ++ ++void ++test_socket_address::test_make() { ++ torrent::sa_unique_ptr sa_unspec = torrent::sa_make_unspec(); ++ CPPUNIT_ASSERT(sa_unspec != nullptr); ++ CPPUNIT_ASSERT(sa_unspec->sa_family == AF_UNSPEC); ++ ++ torrent::sa_unique_ptr sa_inet = torrent::sa_make_inet(); ++ CPPUNIT_ASSERT(sa_inet != nullptr); ++ CPPUNIT_ASSERT(sa_inet->sa_family == AF_INET); ++ ++ sockaddr_in* sin_inet = reinterpret_cast(sa_inet.get()); ++ CPPUNIT_ASSERT(sin_inet->sin_family == AF_INET); ++ CPPUNIT_ASSERT(sin_inet->sin_port == 0); ++ CPPUNIT_ASSERT(sin_inet->sin_addr.s_addr == in_addr().s_addr); ++ ++ torrent::sa_unique_ptr sa_inet6 = torrent::sa_make_inet6(); ++ CPPUNIT_ASSERT(sa_inet6 != nullptr); ++ CPPUNIT_ASSERT(sa_inet6->sa_family == AF_INET6); ++ ++ sockaddr_in6* sin6_inet6 = reinterpret_cast(sa_inet6.get()); ++ CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6); ++ CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0); ++ CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0); ++ CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0})); ++ CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0); ++ ++ torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix(""); ++ CPPUNIT_ASSERT(sa_unix != nullptr); ++ CPPUNIT_ASSERT(sa_unix->sa_family == AF_UNIX); ++} ++ ++void ++test_socket_address::test_sin_from_sa() { ++ torrent::sa_unique_ptr sa_zero = wrap_ai_get_first_sa("0.0.0.0"); ++ torrent::sin_unique_ptr sin_zero; ++ ++ CPPUNIT_ASSERT(sa_zero != nullptr); ++ CPPUNIT_ASSERT_NO_THROW({ sin_zero = torrent::sin_from_sa(std::move(sa_zero)); }); ++ CPPUNIT_ASSERT(sa_zero == nullptr); ++ CPPUNIT_ASSERT(sin_zero != nullptr); ++ ++ CPPUNIT_ASSERT(sin_zero->sin_addr.s_addr == htonl(0x0)); ++ ++ torrent::sa_unique_ptr sa_inet = wrap_ai_get_first_sa("1.2.3.4"); ++ torrent::sin_unique_ptr sin_inet; ++ ++ CPPUNIT_ASSERT(sa_inet != nullptr); ++ CPPUNIT_ASSERT_NO_THROW({ sin_inet = torrent::sin_from_sa(std::move(sa_inet)); }); ++ CPPUNIT_ASSERT(sa_inet == nullptr); ++ CPPUNIT_ASSERT(sin_inet != nullptr); ++ ++ CPPUNIT_ASSERT(sin_inet->sin_addr.s_addr == htonl(0x01020304)); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_unique_ptr()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_make_unspec()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_make_inet6()), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sin6_from_sa() { ++ torrent::sa_unique_ptr sa_zero = wrap_ai_get_first_sa("::"); ++ torrent::sin6_unique_ptr sin6_zero; ++ ++ CPPUNIT_ASSERT(sa_zero != nullptr); ++ CPPUNIT_ASSERT_NO_THROW({ sin6_zero = torrent::sin6_from_sa(std::move(sa_zero)); }); ++ CPPUNIT_ASSERT(sa_zero == nullptr); ++ CPPUNIT_ASSERT(sin6_zero != nullptr); ++ ++ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[0] == 0x0); ++ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[1] == 0x0); ++ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[15] == 0x0); ++ ++ torrent::sa_unique_ptr sa_inet6 = wrap_ai_get_first_sa("ff01::1"); ++ torrent::sin6_unique_ptr sin6_inet6; ++ ++ CPPUNIT_ASSERT(sa_inet6 != nullptr); ++ CPPUNIT_ASSERT_NO_THROW({ sin6_inet6 = torrent::sin6_from_sa(std::move(sa_inet6)); }); ++ CPPUNIT_ASSERT(sa_inet6 == nullptr); ++ CPPUNIT_ASSERT(sin6_inet6 != nullptr); ++ ++ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[0] == 0xff); ++ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[1] == 0x01); ++ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[15] == 0x01); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_unique_ptr()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_make_unspec()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_make_inet()), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sa_equal() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_unspec())); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_inet(), torrent::sa_make_inet())); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_inet6(), torrent::sa_make_inet6())); ++ ++ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_inet())); ++ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_inet6())); ++ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_inet(), torrent::sa_make_inet6())); ++ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_inet6(), torrent::sa_make_inet())); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(sin_1, sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(sin_1, c_sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(c_sin_1, sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(c_sin_1, c_sin_1)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1, sin_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1, c_sin_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin_1, sin_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin_1, c_sin_2)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1, sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1, c_sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(c_sin6_1, sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(c_sin6_1, c_sin6_1)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1, sin6_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1, c_sin6_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin6_1, sin6_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin6_1, c_sin6_2)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(sin_1_5000, sin_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1_5000, sin6_1_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_1_5100)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_1_5100)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_2_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_2_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_2_5100)); ++ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_2_5100)); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sap_equal(torrent::sa_make_unix(""), torrent::sa_make_unix("")), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_equal(torrent::sa_make_unix(""), sin6_1), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_equal(sin6_1, torrent::sa_make_unix("")), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sa_equal_addr() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_unspec())); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_inet(), torrent::sa_make_inet())); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_inet6(), torrent::sa_make_inet6())); ++ ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_inet())); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_inet6())); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_inet(), torrent::sa_make_inet6())); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_inet6(), torrent::sa_make_inet())); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1, sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1, c_sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin_1, sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin_1, c_sin_1)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1, sin_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1, c_sin_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin_1, sin_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin_1, c_sin_2)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1, sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1, c_sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin6_1, sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin6_1, c_sin6_1)); ++ ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1, sin6_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1, c_sin6_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin6_1, sin6_2)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin6_1, c_sin6_2)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1_5000, sin_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1_5000, sin6_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1_5000, sin_1_5100)); ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1_5000, sin6_1_5100)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1_5000, sin_2_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1_5000, sin6_2_5000)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1_5000, sin_2_5100)); ++ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1_5000, sin6_2_5100)); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(torrent::sa_make_unix(""), torrent::sa_make_unix("")), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(torrent::sa_make_unix(""), sin6_1), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(sin6_1, torrent::sa_make_unix("")), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sa_copy() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_unspec()), torrent::sa_make_unspec())); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_inet()), sin_any)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_inet6()), sin6_any)); ++ ++ CPPUNIT_ASSERT(torrent::sap_copy(sin_1).get() != sin_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy(c_sin_1).get() != c_sin_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy(sin6_1).get() != sin6_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy(c_sin6_1).get() != c_sin6_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy(sin_1_5000).get() != sin_1_5000.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy(sin6_1_5000).get() != sin6_1_5000.get()); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1), sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1), c_sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin_1), sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin_1), c_sin_1)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1), sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1), c_sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin6_1), sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin6_1), c_sin6_1)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1_5000), sin_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1_5000), sin6_1_5000)); ++ ++ auto sin6_flags = torrent::sap_copy(sin6_1_5000); ++ reinterpret_cast(sin6_flags.get())->sin6_flowinfo = 0x12345678; ++ reinterpret_cast(sin6_flags.get())->sin6_scope_id = 0x12345678; ++ ++ // TODO: Need 'strict' equal test. ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_flags), sin6_flags)); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sap_copy(torrent::sa_unique_ptr()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_copy(torrent::c_sa_unique_ptr()), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sa_copy_addr() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_unspec()), torrent::sa_make_unspec())); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet()), sin_any)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet6()), sin6_any)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_unspec(), 5000), torrent::sa_make_unspec())); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet(), 5000), sin_any_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet6(), 5000), sin6_any_5000)); ++ ++ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin_1).get() != sin_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy_addr(c_sin_1).get() != c_sin_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin6_1).get() != sin6_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy_addr(c_sin6_1).get() != c_sin6_1.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin_1_5000).get() != sin_1_5000.get()); ++ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin6_1_5000).get() != sin6_1_5000.get()); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1), sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1), c_sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1), sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1), c_sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1, 5000), sin_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1, 5000), c_sin_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1, 5000), sin_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1, 5000), c_sin_1_5000)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1), sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1), c_sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1), sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1), c_sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1, 5000), sin6_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1, 5000), c_sin6_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1, 5000), sin6_1_5000)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1, 5000), c_sin6_1_5000)); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1_5000), sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1_5000), sin6_1)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1_5000, 5100), sin_1_5100)); ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1_5000, 5100), sin6_1_5100)); ++ ++ auto sin6_flags = wrap_ai_get_first_sa("ff01::1", "5555"); ++ reinterpret_cast(sin6_flags.get())->sin6_flowinfo = 0x12345678; ++ reinterpret_cast(sin6_flags.get())->sin6_scope_id = 0x12345678; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_flags), sin6_1)); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::sa_unique_ptr()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::c_sa_unique_ptr()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::sa_unique_ptr(), 5000), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::c_sa_unique_ptr(), 5000), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sa_from_v4mapped() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_any), sin_any)); ++ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_any))); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_1), sin_1)); ++ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_1))); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_bc), sin_bc)); ++ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_bc))); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_unspec()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_inet()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_unix("")), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_any), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_bc), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_1), torrent::internal_error); ++} ++ ++void ++test_socket_address::test_sa_to_v4mapped() { ++ TEST_DEFAULT_SA; ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_any), sin6_v4_any)); ++ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_any))); ++ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_any))); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_bc), sin6_v4_bc)); ++ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_bc))); ++ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_bc))); ++ ++ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_1), sin6_v4_1)); ++ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_1))); ++ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_1))); ++ ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_unspec()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_inet6()), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_unix("")), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_any), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_1), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_any), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_bc), torrent::internal_error); ++ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_1), torrent::internal_error); ++} +diff --git a/test/torrent/net/test_socket_address.h b/test/torrent/net/test_socket_address.h +new file mode 100644 +index 00000000..6157f366 +--- /dev/null ++++ b/test/torrent/net/test_socket_address.h +@@ -0,0 +1,43 @@ ++#include ++ ++class test_socket_address : public CppUnit::TestFixture { ++ CPPUNIT_TEST_SUITE(test_socket_address); ++ ++ CPPUNIT_TEST(test_sa_is_any); ++ CPPUNIT_TEST(test_sa_is_broadcast); ++ ++ CPPUNIT_TEST(test_make); ++ ++ CPPUNIT_TEST(test_sin_from_sa); ++ CPPUNIT_TEST(test_sin6_from_sa); ++ ++ CPPUNIT_TEST(test_sa_equal); ++ CPPUNIT_TEST(test_sa_equal_addr); ++ CPPUNIT_TEST(test_sa_copy); ++ CPPUNIT_TEST(test_sa_copy_addr); ++ ++ CPPUNIT_TEST(test_sa_from_v4mapped); ++ CPPUNIT_TEST(test_sa_to_v4mapped); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void setUp() {} ++ void tearDown() {} ++ ++ void test_sa_is_any(); ++ void test_sa_is_broadcast(); ++ ++ void test_make(); ++ ++ void test_sin_from_sa(); ++ void test_sin6_from_sa(); ++ ++ void test_sa_equal(); ++ void test_sa_equal_addr(); ++ void test_sa_copy(); ++ void test_sa_copy_addr(); ++ ++ void test_sa_from_v4mapped(); ++ void test_sa_to_v4mapped(); ++}; +diff --git a/test/torrent/net/test_socket_address_key.cc b/test/torrent/net/test_socket_address_key.cc +deleted file mode 100644 +index 7892e730..00000000 +--- a/test/torrent/net/test_socket_address_key.cc ++++ /dev/null +@@ -1,87 +0,0 @@ +-#include "config.h" +- +-#include lt_tr1_functional +-#include +-#include +- +-#include "test_socket_address_key.h" +- +-#include "torrent/utils/net.h" +-#include "torrent/net/socket_address_key.h" +- +-CPPUNIT_TEST_SUITE_REGISTRATION(test_socket_address_key); +- +-// TODO: Move into a test utilities header: +- +-typedef std::function addrinfo_ftor; +- +-static torrent::socket_address_key +-test_create_valid(const char* hostname, addrinfo_ftor ftor) { +- struct addrinfo* addr_info; +- +- try { +- addr_info = ftor(); +- } catch (torrent::address_info_error& e) { +- CPPUNIT_ASSERT_MESSAGE("Caught address_info_error for '" + std::string(hostname) + "'", false); +- } +- +- CPPUNIT_ASSERT_MESSAGE("test_create_valid could not find '" + std::string(hostname) + "'", +- addr_info != NULL); +- +- torrent::socket_address_key sock_key = torrent::socket_address_key::from_sockaddr(addr_info->ai_addr); +- +- CPPUNIT_ASSERT_MESSAGE("test_create_valid failed to create valid socket_address_key for '" + std::string(hostname) + "'", +- sock_key.is_valid()); +- +- return sock_key; +-} +- +-static bool +-test_create_throws(const char* hostname, addrinfo_ftor ftor) { +- try { +- ftor(); +- +- return false; +- } catch (torrent::address_info_error& e) { +- return true; +- } +-} +- +-static torrent::socket_address_key +-test_create_inet(const char* hostname) { +- return test_create_valid(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET, 0)); +-} +- +-static bool +-test_create_inet_throws(const char* hostname) { +- return test_create_throws(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET, 0)); +-} +- +-static torrent::socket_address_key +-test_create_inet6(const char* hostname) { +- return test_create_valid(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET6, 0)); +-} +- +-static bool +-test_create_inet6_throws(const char* hostname) { +- return test_create_throws(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET6, 0)); +-} +- +-// +-// Basic tests: +-// +- +-void +-test_socket_address_key::test_basic() { +- CPPUNIT_ASSERT(test_create_inet("1.1.1.1").is_valid()); +- CPPUNIT_ASSERT(test_create_inet_throws("1.1.1.300")); +- +- CPPUNIT_ASSERT(test_create_inet6("ff01::1").is_valid()); +- CPPUNIT_ASSERT(test_create_inet6("2001:0db8:85a3:0000:0000:8a2e:0370:7334").is_valid()); +- CPPUNIT_ASSERT(test_create_inet6("2001:db8:a::123").is_valid()); +- +- CPPUNIT_ASSERT(test_create_inet6_throws("2001:db8:a::22123")); +-} +- +- +-// Test lexical comparison: +diff --git a/test/torrent/object_stream_test.cc b/test/torrent/object_stream_test.cc +index c8a17049..5ad0c23e 100644 +--- a/test/torrent/object_stream_test.cc ++++ b/test/torrent/object_stream_test.cc +@@ -1,10 +1,8 @@ + #include "config.h" + +-#define __STDC_CONSTANT_MACROS +- + #include + #include +-#include ++#include + #include + + #include "object_stream_test.h" +diff --git a/test/torrent/tracker_controller_features.cc b/test/torrent/tracker_controller_features.cc +index 63f163f5..0a6a57d6 100644 +--- a/test/torrent/tracker_controller_features.cc ++++ b/test/torrent/tracker_controller_features.cc +@@ -1,7 +1,7 @@ + #include "config.h" + ++#include + #include +-#include lt_tr1_functional + + #include "rak/priority_queue_default.h" + +diff --git a/test/torrent/tracker_controller_requesting.cc b/test/torrent/tracker_controller_requesting.cc +index 5bc25169..92e664b3 100644 +--- a/test/torrent/tracker_controller_requesting.cc ++++ b/test/torrent/tracker_controller_requesting.cc +@@ -1,7 +1,7 @@ + #include "config.h" + ++#include + #include +-#include lt_tr1_functional + + #include "rak/priority_queue_default.h" + +diff --git a/test/torrent/tracker_controller_test.cc b/test/torrent/tracker_controller_test.cc +index 823a9d34..9406c99e 100644 +--- a/test/torrent/tracker_controller_test.cc ++++ b/test/torrent/tracker_controller_test.cc +@@ -1,7 +1,7 @@ + #include "config.h" + ++#include + #include +-#include lt_tr1_functional + + #include "rak/priority_queue_default.h" + +diff --git a/test/torrent/tracker_list_features_test.cc b/test/torrent/tracker_list_features_test.cc +index 57c05f40..5257b1a7 100644 +--- a/test/torrent/tracker_list_features_test.cc ++++ b/test/torrent/tracker_list_features_test.cc +@@ -1,6 +1,6 @@ + #include "config.h" + +-#include lt_tr1_functional ++#include + + #include "torrent/http.h" + #include "net/address_list.h" +diff --git a/test/torrent/utils/directory_events_test.cc b/test/torrent/utils/directory_events_test.cc +index 2cea5ab5..b97fd1d4 100644 +--- a/test/torrent/utils/directory_events_test.cc ++++ b/test/torrent/utils/directory_events_test.cc +@@ -1,6 +1,6 @@ + #include "config.h" + +-#include ++#include + #include + #include + +@@ -8,8 +8,6 @@ + + CPPUNIT_TEST_SUITE_REGISTRATION(utils_directory_events_test); + +-namespace tr1 { using namespace std::tr1; } +- + void + utils_directory_events_test::setUp() { + } +diff --git a/test/torrent/utils/log_buffer_test.h b/test/torrent/utils/log_buffer_test.h +deleted file mode 100644 +index f2824594..00000000 +--- a/test/torrent/utils/log_buffer_test.h ++++ /dev/null +@@ -1,17 +0,0 @@ +-#include +- +-#include "torrent/utils/log_buffer.h" +- +-class utils_log_buffer_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(utils_log_buffer_test); +- CPPUNIT_TEST(test_basic); +- CPPUNIT_TEST(test_timestamps); +- CPPUNIT_TEST_SUITE_END(); +- +-public: +- void setUp(); +- void tearDown(); +- +- void test_basic(); +- void test_timestamps(); +-}; +diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc +index 9f975636..8cc00ef8 100644 +--- a/test/torrent/utils/log_test.cc ++++ b/test/torrent/utils/log_test.cc +@@ -3,8 +3,9 @@ + #include + #include + #include ++#include + #include +-#include lt_tr1_functional ++ + #include + #include + +@@ -37,6 +38,7 @@ void + utils_log_test::setUp() { + // Don't initialize since this creates the group->child connections. + // torrent::log_initialize(); ++ torrent::log_cleanup(); + } + + void +diff --git a/test/torrent/utils/net_test.cc b/test/torrent/utils/net_test.cc +deleted file mode 100644 +index d136e869..00000000 +--- a/test/torrent/utils/net_test.cc ++++ /dev/null +@@ -1,32 +0,0 @@ +-#include "config.h" +- +-#include +-#include +- +-#include "net_test.h" +- +-CPPUNIT_TEST_SUITE_REGISTRATION(utils_net_test); +- +-static void inc_value(int* value) { (*value)++; } +- +-#define LTUNIT_AI_CALL(lt_ai, lt_flags) { \ +- int test_value = 0; \ +- CPPUNIT_ASSERT(torrent::address_info_call(ai, 0, std::bind(&inc_value, &test_value))); \ +- CPPUNIT_ASSERT(test_value); } \ +- +-void +-utils_net_test::setUp() { +-} +- +-void +-utils_net_test::tearDown() { +-} +- +-void +-utils_net_test::test_basic() { +- addrinfo* ai = torrent::address_info_lookup("localhost", AF_INET, SOCK_STREAM); +- +- LTUNIT_AI_CALL(ai, 0); +- +- torrent::address_info_free(ai); +-} +diff --git a/test/torrent/utils/net_test.h b/test/torrent/utils/net_test.h +deleted file mode 100644 +index e538ab39..00000000 +--- a/test/torrent/utils/net_test.h ++++ /dev/null +@@ -1,15 +0,0 @@ +-#include +- +-#include "torrent/utils/net.h" +- +-class utils_net_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(utils_net_test); +- CPPUNIT_TEST(test_basic); +- CPPUNIT_TEST_SUITE_END(); +- +-public: +- void setUp(); +- void tearDown(); +- +- void test_basic(); +-}; +diff --git a/test/torrent/utils/option_strings_test.cc b/test/torrent/utils/option_strings_test.cc +index c6302f98..a9bdcc89 100644 +--- a/test/torrent/utils/option_strings_test.cc ++++ b/test/torrent/utils/option_strings_test.cc +@@ -1,8 +1,9 @@ + #include "config.h" + + #include ++#include + #include +-#include lt_tr1_functional ++ + #include + #include + +diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc +index d6b8d11d..87424d62 100644 +--- a/test/torrent/utils/test_extents.cc ++++ b/test/torrent/utils/test_extents.cc +@@ -2,7 +2,7 @@ + + #include "test_extents.h" + +-#include ++#include + #include + #include + +diff --git a/test/torrent/utils/log_buffer_test.cc b/test/torrent/utils/test_log_buffer.cc +similarity index 86% +rename from test/torrent/utils/log_buffer_test.cc +rename to test/torrent/utils/test_log_buffer.cc +index a0ede0a0..a56a5365 100644 +--- a/test/torrent/utils/log_buffer_test.cc ++++ b/test/torrent/utils/test_log_buffer.cc +@@ -1,23 +1,23 @@ + #include "config.h" + +-#include ++#include "test_log_buffer.h" + + #include "globals.h" +-#include "log_buffer_test.h" ++#include + +-CPPUNIT_TEST_SUITE_REGISTRATION(utils_log_buffer_test); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log_buffer, "torrent/utils"); + + void +-utils_log_buffer_test::setUp() { ++test_log_buffer::setUp() { + torrent::cachedTime = rak::timer::from_seconds(1000); + } + + void +-utils_log_buffer_test::tearDown() { ++test_log_buffer::tearDown() { + } + + void +-utils_log_buffer_test::test_basic() { ++test_log_buffer::test_basic() { + torrent::log_buffer log; + + log.lock(); +@@ -44,7 +44,7 @@ utils_log_buffer_test::test_basic() { + } + + void +-utils_log_buffer_test::test_timestamps() { ++test_log_buffer::test_timestamps() { + torrent::log_buffer log; + + log.lock_and_push_log("foobar", 6, 0); +diff --git a/test/torrent/utils/test_log_buffer.h b/test/torrent/utils/test_log_buffer.h +new file mode 100644 +index 00000000..290df4c1 +--- /dev/null ++++ b/test/torrent/utils/test_log_buffer.h +@@ -0,0 +1,17 @@ ++#include "helpers/test_fixture.h" ++ ++class test_log_buffer : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_log_buffer); ++ ++ CPPUNIT_TEST(test_basic); ++ CPPUNIT_TEST(test_timestamps); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void setUp(); ++ void tearDown(); ++ ++ void test_basic(); ++ void test_timestamps(); ++}; +diff --git a/test/torrent/utils/test_uri_parser.cc b/test/torrent/utils/test_uri_parser.cc +index c3b46eef..1f4bebe8 100644 +--- a/test/torrent/utils/test_uri_parser.cc ++++ b/test/torrent/utils/test_uri_parser.cc +@@ -2,7 +2,7 @@ + + #include "test_uri_parser.h" + +-#include ++#include + #include + #include + +diff --git a/test/torrent/utils/thread_base_test.cc b/test/torrent/utils/thread_base_test.cc +index 5cb7553f..8366c9ba 100644 +--- a/test/torrent/utils/thread_base_test.cc ++++ b/test/torrent/utils/thread_base_test.cc +@@ -1,7 +1,8 @@ + #include "config.h" + ++#include + #include +-#include lt_tr1_functional ++ + #include + #include + #include 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 000000000..d81548ceb --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch @@ -0,0 +1,26 @@ +From b656a77864bd322d69522f1f9d922404066e5a7c Mon Sep 17 00:00:00 2001 +From: Fabrice Fontaine +Date: Mon, 21 Oct 2019 09:32:15 +0200 +Subject: [PATCH] libtorrent.pc.in: add Libs.Private (#202) + +Add Libs.Private: -lz so applications that want to link statically with +libtorrent (such as rtorrent) will know that they must link with -lz + +Fixes: + - http://autobuild.buildroot.org/results/075598e1699c2ac20a4dfbcb5695bbb7343f9a86 + +Signed-off-by: Fabrice Fontaine +--- + libtorrent.pc.in | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/libtorrent.pc.in b/libtorrent.pc.in +index cf6612bc..6108f7e9 100644 +--- a/libtorrent.pc.in ++++ b/libtorrent.pc.in +@@ -7,4 +7,5 @@ Name: libtorrent + Description: A BitTorrent library + Version: @VERSION@ + Libs: -L${libdir} -ltorrent ++Libs.Private: -lz + Cflags: -I${includedir} 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 000000000..59cf76cad --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch @@ -0,0 +1,27 @@ +From 7c80dc3e3a47dd996ca0554fce4f69d16761a9c9 Mon Sep 17 00:00:00 2001 +From: Tadej Obrstar +Date: Sun, 1 Dec 2019 06:59:25 +0100 +Subject: [PATCH] Fix for inotify missing quickly renamed files (#203) + +--- + src/torrent/utils/directory_events.cc | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/src/torrent/utils/directory_events.cc b/src/torrent/utils/directory_events.cc +index 5d789f4e..8dcc2a61 100644 +--- a/src/torrent/utils/directory_events.cc ++++ b/src/torrent/utils/directory_events.cc +@@ -154,8 +154,11 @@ directory_events::event_read() { + wd_list::const_iterator itr = std::find_if(m_wd_list.begin(), m_wd_list.end(), + std::bind(&watch_descriptor::compare_desc, std::placeholders::_1, event->wd)); + +- if (itr != m_wd_list.end()) +- itr->slot(itr->path + event->name); ++ if (itr != m_wd_list.end()) { ++ std::string sname(event->name); ++ if((sname.substr(sname.find_last_of(".") ) == ".torrent")) ++ itr->slot(itr->path + event->name); ++ } + + event = (struct inotify_event*)(next_event); + } 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 000000000..5b26f959f --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch @@ -0,0 +1,470 @@ +From 81897862edea81e9620493c473f488d1820bcf93 Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Tue, 3 Dec 2019 21:53:48 +0900 +Subject: [PATCH] Fix compiler warnings. (#204) + +--- + configure.ac | 6 ++- + scripts/ax_execinfo.m4 | 67 +++++++++++++++++++++++++++++++ + scripts/common.m4 | 15 ------- + scripts/rak_execinfo.m4 | 11 +++++ + src/torrent/exceptions.cc | 4 +- + test/Makefile.am | 15 ++----- + test/helpers/expect_fd.h | 8 ++-- + test/helpers/mock_compare.h | 6 +-- + test/helpers/progress_listener.cc | 3 +- + test/main.cc | 4 +- + test/net/Makefile.am | 40 ++++++++++++++++++ + test/torrent/net/Makefile.am | 44 ++++++++++++++++++++ + test/torrent/net/test_fd.cc | 48 +++++++++++----------- + 13 files changed, 207 insertions(+), 64 deletions(-) + create mode 100644 scripts/ax_execinfo.m4 + create mode 100644 scripts/rak_execinfo.m4 + create mode 100644 test/net/Makefile.am + create mode 100644 test/torrent/net/Makefile.am + +diff --git a/configure.ac b/configure.ac +index 620ca552..b6708366 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -33,6 +33,7 @@ RAK_CHECK_CXXFLAGS + RAK_ENABLE_DEBUG + RAK_ENABLE_EXTRA_DEBUG + RAK_ENABLE_WERROR ++RAK_DISABLE_BACKTRACE + + RAK_CHECK_CXX11 + +@@ -57,8 +58,8 @@ TORRENT_WITH_INOTIFY + + CC_ATTRIBUTE_VISIBILITY + +-AX_PTHREAD + AX_CHECK_ZLIB ++AX_PTHREAD + + PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"]) + +@@ -74,7 +75,6 @@ AC_CHECK_FUNCS(posix_memalign) + TORRENT_CHECK_MADVISE() + TORRENT_CHECK_CACHELINE() + TORRENT_CHECK_POPCOUNT() +-TORRENT_CHECK_EXECINFO() + TORRENT_CHECK_PTHREAD_SETNAME_NP() + TORRENT_MINCORE() + +@@ -111,4 +111,6 @@ AC_OUTPUT([ + src/tracker/Makefile + src/utils/Makefile + test/Makefile ++ test/torrent/net/Makefile ++ test/net/Makefile + ]) +diff --git a/scripts/ax_execinfo.m4 b/scripts/ax_execinfo.m4 +new file mode 100644 +index 00000000..0ff5fc0e +--- /dev/null ++++ b/scripts/ax_execinfo.m4 +@@ -0,0 +1,67 @@ ++# =========================================================================== ++# https://www.gnu.org/software/autoconf-archive/ax_execinfo.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_EXECINFO([ACTION-IF-EXECINFO-H-IS-FOUND], [ACTION-IF-EXECINFO-H-IS-NOT-FOUND], [ADDITIONAL-TYPES-LIST]) ++# ++# DESCRIPTION ++# ++# Checks for execinfo.h header and if the len parameter/return type can be ++# found from a list, also define backtrace_size_t to that type. ++# ++# By default the list of types to try contains int and size_t, but should ++# some yet undiscovered system use e.g. unsigned, the 3rd argument can be ++# used for extensions. I'd like to hear of further suggestions. ++# ++# Executes ACTION-IF-EXECINFO-H-IS-FOUND when present and the execinfo.h ++# header is found or ACTION-IF-EXECINFO-H-IS-NOT-FOUND in case the header ++# seems unavailable. ++# ++# Also adds -lexecinfo to LIBS on BSD if needed. ++# ++# LICENSE ++# ++# Copyright (c) 2014 Thomas Jahns ++# ++# Copying and distribution of this file, with or without modification, are ++# permitted in any medium without royalty provided the copyright notice ++# and this notice are preserved. This file is offered as-is, without any ++# warranty. ++ ++#serial 2 ++ ++AC_DEFUN([AX_EXECINFO], ++ [AC_CHECK_HEADERS([execinfo.h]) ++ AS_IF([test x"$ac_cv_header_execinfo_h" = xyes], ++ [AC_CACHE_CHECK([size parameter type for backtrace()], ++ [ax_cv_proto_backtrace_type], ++ [AC_LANG_PUSH([C]) ++ for ax_cv_proto_backtrace_type in size_t int m4_ifnblank([$3],[$3 ])none; do ++ AS_IF([test "${ax_cv_proto_backtrace_type}" = none], ++ [ax_cv_proto_backtrace_type= ; break]) ++ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ ++#include ++extern ++${ax_cv_proto_backtrace_type} backtrace(void **addrlist, ${ax_cv_proto_backtrace_type} len); ++char **backtrace_symbols(void *const *buffer, ${ax_cv_proto_backtrace_type} size); ++])], ++ [break]) ++ done ++ AC_LANG_POP([C])])]) ++ AS_IF([test x${ax_cv_proto_backtrace_type} != x], ++ [AC_DEFINE_UNQUOTED([backtrace_size_t], [$ax_cv_proto_backtrace_type], ++ [Defined to return type of backtrace().])]) ++ AC_SEARCH_LIBS([backtrace],[execinfo]) ++ AS_IF([test x"${ax_cv_proto_backtrace_type}" != x -a x"$ac_cv_header_execinfo_h" = xyes -a x"$ac_cv_search_backtrace" != xno], ++ [AC_DEFINE([HAVE_BACKTRACE],[1], ++ [Defined if backtrace() could be fully identified.]) ++ ]m4_ifnblank([$1],[$1 ++]),m4_ifnblank([$2],[$2 ++]))]) ++dnl ++dnl Local Variables: ++dnl mode: autoconf ++dnl End: ++dnl +diff --git a/scripts/common.m4 b/scripts/common.m4 +index b6d051f5..55e8d66e 100644 +--- a/scripts/common.m4 ++++ b/scripts/common.m4 +@@ -150,21 +150,6 @@ dnl Need to fix this so that it uses the stuff defined by the system. + ]) + ]) + +-AC_DEFUN([TORRENT_CHECK_EXECINFO], [ +- AC_MSG_CHECKING(for execinfo.h) +- +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([ +- #include +- int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;} +- ])], +- [ +- AC_MSG_RESULT(yes) +- AC_DEFINE(USE_EXECINFO, 1, Use execinfo.h) +- ], [ +- AC_MSG_RESULT(no) +- ]) +-]) +- + AC_DEFUN([TORRENT_CHECK_ALIGNED], [ + AC_MSG_CHECKING(the byte alignment) + +diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4 +new file mode 100644 +index 00000000..c1d9b2f8 +--- /dev/null ++++ b/scripts/rak_execinfo.m4 +@@ -0,0 +1,11 @@ ++AC_DEFUN([RAK_DISABLE_BACKTRACE], [ ++ AC_ARG_ENABLE(backtrace, ++ AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]), ++ [ ++ if test "$enableval" = "yes"; then ++ AX_EXECINFO ++ fi ++ ],[ ++ AX_EXECINFO ++ ]) ++]) +diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc +index 2aeca1d7..f834f9fa 100644 +--- a/src/torrent/exceptions.cc ++++ b/src/torrent/exceptions.cc +@@ -42,7 +42,7 @@ + #include + #include + +-#ifdef USE_EXECINFO ++#ifdef HAVE_BACKTRACE + #include + #endif + +@@ -75,7 +75,7 @@ internal_error::initialize(const std::string& msg) { + + std::stringstream output; + +-#ifdef USE_EXECINFO ++#ifdef HAVE_BACKTRACE + void* stackPtrs[20]; + + // Print the stack and exit. +diff --git a/test/Makefile.am b/test/Makefile.am +index b60a86a6..23b260e4 100644 +--- a/test/Makefile.am ++++ b/test/Makefile.am +@@ -1,3 +1,5 @@ ++SUBDIRS = torrent/net net ++ + TESTS = LibTorrentTest + AUTOMAKE_OPTIONS = subdir-objects + +@@ -43,19 +45,9 @@ LibTorrentTest_SOURCES = \ + data/hash_queue_test.cc \ + data/hash_queue_test.h \ + \ +- net/test_socket_listen.cc \ +- net/test_socket_listen.h \ +- \ + protocol/test_request_list.cc \ + protocol/test_request_list.h \ + \ +- torrent/net/test_address_info.cc \ +- torrent/net/test_address_info.h \ +- torrent/net/test_fd.cc \ +- torrent/net/test_fd.h \ +- torrent/net/test_socket_address.cc \ +- torrent/net/test_socket_address.h \ +- \ + torrent/utils/log_test.cc \ + torrent/utils/log_test.h \ + torrent/utils/option_strings_test.cc \ +@@ -97,9 +89,10 @@ LibTorrentTest_SOURCES = \ + torrent/tracker_timeout_test.h \ + tracker/tracker_http_test.cc \ + tracker/tracker_http_test.h \ ++ \ + main.cc + + LibTorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS) +-LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl + + AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src +diff --git a/test/helpers/expect_fd.h b/test/helpers/expect_fd.h +index 178cbabc..cc77c34a 100644 +--- a/test/helpers/expect_fd.h ++++ b/test/helpers/expect_fd.h +@@ -18,15 +18,15 @@ sap_cache_copy_addr_c_ptr(sap_cache_type& sap_cache, const torrent::c_sa_unique_ + + inline void + expect_event_open_re(int idx) { +- mock_expect(&torrent::poll_event_open, mock_compare_map::begin_pointer + idx); +- mock_expect(&torrent::poll_event_insert_read, mock_compare_map::begin_pointer + idx); +- mock_expect(&torrent::poll_event_insert_error, mock_compare_map::begin_pointer + idx); ++ mock_expect(&torrent::poll_event_open, mock_compare_map::begin_pointer() + idx); ++ mock_expect(&torrent::poll_event_insert_read, mock_compare_map::begin_pointer() + idx); ++ mock_expect(&torrent::poll_event_insert_error, mock_compare_map::begin_pointer() + idx); + } + + inline void + expect_event_closed_fd(int idx, int fd) { + mock_expect(&torrent::fd__close, 0, fd); +- mock_expect(&torrent::poll_event_closed, mock_compare_map::begin_pointer + idx); ++ mock_expect(&torrent::poll_event_closed, mock_compare_map::begin_pointer() + idx); + } + + inline void +diff --git a/test/helpers/mock_compare.h b/test/helpers/mock_compare.h +index 3ea90305..3cc8d075 100644 +--- a/test/helpers/mock_compare.h ++++ b/test/helpers/mock_compare.h +@@ -34,11 +34,11 @@ template + struct mock_compare_map { + typedef std::map values_type; + +- constexpr static T* begin_pointer = reinterpret_cast(0x1000); +- constexpr static T* end_pointer = reinterpret_cast(0x2000); ++ static T* begin_pointer() { return reinterpret_cast(0x1000); } ++ static T* end_pointer() { return reinterpret_cast(0x2000); } + + static bool is_key(const T* k) { +- return k >= begin_pointer && k < end_pointer; ++ return k >= begin_pointer() && k < end_pointer(); + } + + static bool has_key(const T* k) { +diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc +index 02803ffc..c2b60bcd 100644 +--- a/test/helpers/progress_listener.cc ++++ b/test/helpers/progress_listener.cc +@@ -54,7 +54,8 @@ void + progress_listener::startSuite(CppUnit::Test *suite) { + m_test_path.push_back(suite); + +- std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl; ++ if (suite->countTestCases() > 0) ++ std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl; + } + + void +diff --git a/test/main.cc b/test/main.cc +index da93fead..e8a00e1f 100644 +--- a/test/main.cc ++++ b/test/main.cc +@@ -12,7 +12,7 @@ + #include + #include + +-#ifdef USE_EXECINFO ++#ifdef HAVE_BACKTRACE + #include + #endif + +@@ -29,7 +29,7 @@ do_test_panic(int signum) { + + std::cout << std::endl << std::endl << "Caught " << strsignal(signum) << ", dumping stack:" << std::endl << std::endl; + +-#ifdef USE_EXECINFO ++#ifdef HAVE_BACKTRACE + void* stackPtrs[20]; + + // Print the stack and exit. +diff --git a/test/net/Makefile.am b/test/net/Makefile.am +new file mode 100644 +index 00000000..bb951814 +--- /dev/null ++++ b/test/net/Makefile.am +@@ -0,0 +1,40 @@ ++TESTS = LibTorrentTestNet ++AUTOMAKE_OPTIONS = subdir-objects ++ ++check_PROGRAMS = $(TESTS) ++LibTorrentTestNet_LDADD = \ ++ ../../src/libtorrent.la \ ++ ../../src/torrent/libsub_torrent.la \ ++ ../../src/torrent/data/libsub_torrentdata.la \ ++ ../../src/torrent/download/libsub_torrentdownload.la \ ++ ../../src/torrent/peer/libsub_torrentpeer.la \ ++ ../../src/data/libsub_data.la \ ++ ../../src/dht/libsub_dht.la \ ++ ../../src/net/libsub_net.la \ ++ ../../src/protocol/libsub_protocol.la \ ++ ../../src/download/libsub_download.la \ ++ ../../src/tracker/libsub_tracker.la \ ++ ../../src/utils/libsub_utils.la \ ++ ../../src/torrent/utils/libsub_torrentutils.la ++ ++LibTorrentTestNet_SOURCES = \ ++ ../helpers/expect_fd.h \ ++ ../helpers/expect_utils.h \ ++ ../helpers/mock_compare.h \ ++ ../helpers/mock_function.cc \ ++ ../helpers/mock_function.h \ ++ ../helpers/network.h \ ++ ../helpers/progress_listener.cc \ ++ ../helpers/progress_listener.h \ ++ ../helpers/test_fixture.cc \ ++ ../helpers/test_fixture.h \ ++ \ ++ test_socket_listen.cc \ ++ test_socket_listen.h \ ++ \ ++ ../main.cc ++ ++LibTorrentTestNet_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrentTestNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++ ++AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test +diff --git a/test/torrent/net/Makefile.am b/test/torrent/net/Makefile.am +new file mode 100644 +index 00000000..8a531cc1 +--- /dev/null ++++ b/test/torrent/net/Makefile.am +@@ -0,0 +1,44 @@ ++TESTS = LibTorrentTestTorrentNet ++AUTOMAKE_OPTIONS = subdir-objects ++ ++check_PROGRAMS = $(TESTS) ++LibTorrentTestTorrentNet_LDADD = \ ++ ../../../src/libtorrent.la \ ++ ../../../src/torrent/libsub_torrent.la \ ++ ../../../src/torrent/data/libsub_torrentdata.la \ ++ ../../../src/torrent/download/libsub_torrentdownload.la \ ++ ../../../src/torrent/peer/libsub_torrentpeer.la \ ++ ../../../src/data/libsub_data.la \ ++ ../../../src/dht/libsub_dht.la \ ++ ../../../src/net/libsub_net.la \ ++ ../../../src/protocol/libsub_protocol.la \ ++ ../../../src/download/libsub_download.la \ ++ ../../../src/tracker/libsub_tracker.la \ ++ ../../../src/utils/libsub_utils.la \ ++ ../../../src/torrent/utils/libsub_torrentutils.la ++ ++LibTorrentTestTorrentNet_SOURCES = \ ++ ../../helpers/expect_fd.h \ ++ ../../helpers/expect_utils.h \ ++ ../../helpers/mock_compare.h \ ++ ../../helpers/mock_function.cc \ ++ ../../helpers/mock_function.h \ ++ ../../helpers/network.h \ ++ ../../helpers/progress_listener.cc \ ++ ../../helpers/progress_listener.h \ ++ ../../helpers/test_fixture.cc \ ++ ../../helpers/test_fixture.h \ ++ \ ++ test_address_info.cc \ ++ test_address_info.h \ ++ test_fd.cc \ ++ test_fd.h \ ++ test_socket_address.cc \ ++ test_socket_address.h \ ++ \ ++ ../../main.cc ++ ++LibTorrentTestTorrentNet_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrentTestTorrentNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++ ++AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test +diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc +index 3cab0c5e..5e56f0f3 100644 +--- a/test/torrent/net/test_fd.cc ++++ b/test/torrent/net/test_fd.cc +@@ -1,24 +1,24 @@ +-#include "config.h" +- +-#include "test_fd.h" +- +-#include +- +-CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net"); +- +-void +-test_fd::test_valid_flags() { +- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream)); +- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock)); +- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address)); +- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only)); +- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only)); +- +- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only)); +- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); +- +- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags())); +- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all))); +- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all))); +- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132))); +-} ++#include "config.h" ++ ++#include "test_fd.h" ++ ++#include ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net"); ++ ++void ++test_fd::test_valid_flags() { ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only)); ++ ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only)); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); ++ ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags())); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all))); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all))); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132))); ++} diff --git a/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 000000000..0ecc0cfe5 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch @@ -0,0 +1,33 @@ +From e813c344b1e4aa89288febb2f59109972083f1bb Mon Sep 17 00:00:00 2001 +From: Rosen Penev +Date: Thu, 5 Dec 2019 01:55:53 -0800 +Subject: [PATCH] Fix log format so GCC can check it. (#205) + +--- + src/torrent/utils/log.cc | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc +index b855a2c6..24932996 100644 +--- a/src/torrent/utils/log.cc ++++ b/src/torrent/utils/log.cc +@@ -16,6 +16,8 @@ + #include + #include + ++#define GROUPFMT (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ") ++ + namespace torrent { + + struct log_cache_entry { +@@ -356,9 +358,7 @@ log_gz_file_write(std::shared_ptr& outfile, const char* data, siz + + // Normal groups are nul-terminated strings. + if (group >= 0) { +- const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c "); +- +- int buffer_length = snprintf(buffer, 64, fmt, ++ int buffer_length = snprintf(buffer, 64, GROUPFMT, + cachedTime.seconds(), + log_level_char[group % 6]); + 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 000000000..fa5cb294c --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch @@ -0,0 +1,843 @@ +From 7b85e112ac2f59a39afa344148a946553c776142 Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Fri, 6 Dec 2019 00:35:21 +0900 +Subject: [PATCH] Consolidate make script to optimize build. (#206) + +--- + configure.ac | 14 +-- + src/Makefile.am | 147 ++++++++++++++++++++++++----- + src/data/Makefile.am | 28 ------ + src/dht/Makefile.am | 18 ---- + src/download/Makefile.am | 19 ---- + src/net/Makefile.am | 30 ------ + src/protocol/Makefile.am | 28 ------ + src/torrent/Makefile.am | 154 ++++++++++++++++++++++++++++--- + src/torrent/download/Makefile.am | 22 ----- + src/torrent/net/Makefile.am | 25 ----- + src/torrent/peer/Makefile.am | 28 ------ + src/torrent/utils/Makefile.am | 41 -------- + src/tracker/Makefile.am | 11 --- + src/utils/Makefile.am | 14 --- + test/Makefile.am | 92 +++++++++++++----- + 15 files changed, 338 insertions(+), 333 deletions(-) + delete mode 100644 src/data/Makefile.am + delete mode 100644 src/dht/Makefile.am + delete mode 100644 src/download/Makefile.am + delete mode 100644 src/net/Makefile.am + delete mode 100644 src/protocol/Makefile.am + delete mode 100644 src/torrent/download/Makefile.am + delete mode 100644 src/torrent/net/Makefile.am + delete mode 100644 src/torrent/peer/Makefile.am + delete mode 100644 src/torrent/utils/Makefile.am + delete mode 100644 src/tracker/Makefile.am + delete mode 100644 src/utils/Makefile.am + +diff --git a/configure.ac b/configure.ac +index b6708366..e83710cc 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -17,7 +17,7 @@ AC_SUBST(LIBTORRENT_CURRENT) + AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO) + AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO) + +-AM_INIT_AUTOMAKE([serial-tests]) ++AM_INIT_AUTOMAKE([serial-tests subdir-objects]) + AC_CONFIG_HEADERS(config.h) + + AC_PROG_CXX +@@ -98,18 +98,6 @@ AC_OUTPUT([ + Makefile + src/Makefile + src/torrent/Makefile +- src/torrent/data/Makefile +- src/torrent/download/Makefile +- src/torrent/net/Makefile +- src/torrent/peer/Makefile +- src/torrent/utils/Makefile +- src/data/Makefile +- src/dht/Makefile +- src/download/Makefile +- src/net/Makefile +- src/protocol/Makefile +- src/tracker/Makefile +- src/utils/Makefile + test/Makefile + test/torrent/net/Makefile + test/net/Makefile +diff --git a/src/Makefile.am b/src/Makefile.am +index 99aaace0..e96bd74b 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,30 +1,12 @@ +-SUBDIRS = \ +- torrent \ +- data \ +- dht \ +- download \ +- net \ +- protocol \ +- tracker \ +- utils ++SUBDIRS = torrent + + lib_LTLIBRARIES = libtorrent.la ++noinst_LTLIBRARIES = libtorrent_other.la + + libtorrent_la_LDFLAGS = -version-info $(LIBTORRENT_INTERFACE_VERSION_INFO) + libtorrent_la_LIBADD = \ +- torrent/libsub_torrent.la \ +- torrent/data/libsub_torrentdata.la \ +- torrent/download/libsub_torrentdownload.la \ +- torrent/net/libsub_torrentnet.la \ +- torrent/peer/libsub_torrentpeer.la \ +- torrent/utils/libsub_torrentutils.la \ +- data/libsub_data.la \ +- dht/libsub_dht.la \ +- download/libsub_download.la \ +- net/libsub_net.la \ +- protocol/libsub_protocol.la \ +- tracker/libsub_tracker.la \ +- utils/libsub_utils.la ++ torrent/libtorrent_torrent.la \ ++ libtorrent_other.la + + libtorrent_la_SOURCES = \ + globals.cc \ +@@ -36,4 +18,125 @@ libtorrent_la_SOURCES = \ + thread_main.cc \ + thread_main.h + ++libtorrent_other_la_SOURCES = \ ++ data/chunk.cc \ ++ data/chunk.h \ ++ data/chunk_handle.h \ ++ data/chunk_iterator.h \ ++ data/chunk_list.cc \ ++ data/chunk_list.h \ ++ data/chunk_list_node.h \ ++ data/chunk_part.cc \ ++ data/chunk_part.h \ ++ data/hash_check_queue.cc \ ++ data/hash_check_queue.h \ ++ data/hash_chunk.cc \ ++ data/hash_chunk.h \ ++ data/hash_queue.cc \ ++ data/hash_queue.h \ ++ data/hash_queue_node.cc \ ++ data/hash_queue_node.h \ ++ data/hash_torrent.cc \ ++ data/hash_torrent.h \ ++ data/memory_chunk.cc \ ++ data/memory_chunk.h \ ++ data/socket_file.cc \ ++ data/socket_file.h \ ++ \ ++ dht/dht_bucket.cc \ ++ dht/dht_bucket.h \ ++ dht/dht_hash_map.h \ ++ dht/dht_node.cc \ ++ dht/dht_node.h \ ++ dht/dht_router.cc \ ++ dht/dht_router.h \ ++ dht/dht_server.cc \ ++ dht/dht_server.h \ ++ dht/dht_tracker.cc \ ++ dht/dht_tracker.h \ ++ dht/dht_transaction.cc \ ++ dht/dht_transaction.h \ ++ \ ++ download/available_list.cc \ ++ download/available_list.h \ ++ download/chunk_selector.cc \ ++ download/chunk_selector.h \ ++ download/chunk_statistics.cc \ ++ download/chunk_statistics.h \ ++ download/delegator.cc \ ++ download/delegator.h \ ++ download/download_constructor.cc \ ++ download/download_constructor.h \ ++ download/download_main.cc \ ++ download/download_main.h \ ++ download/download_wrapper.cc \ ++ download/download_wrapper.h \ ++ \ ++ net/address_list.cc \ ++ net/address_list.h \ ++ net/data_buffer.h \ ++ net/local_addr.cc \ ++ net/local_addr.h \ ++ net/listen.cc \ ++ net/listen.h \ ++ net/protocol_buffer.h \ ++ net/socket_base.cc \ ++ net/socket_base.h \ ++ net/socket_datagram.cc \ ++ net/socket_datagram.h \ ++ net/socket_fd.cc \ ++ net/socket_fd.h \ ++ net/socket_listen.cc \ ++ net/socket_listen.h \ ++ net/socket_set.cc \ ++ net/socket_set.h \ ++ net/socket_stream.cc \ ++ net/socket_stream.h \ ++ net/throttle_internal.cc \ ++ net/throttle_internal.h \ ++ net/throttle_list.cc \ ++ net/throttle_list.h \ ++ net/throttle_node.h \ ++ \ ++ protocol/encryption_info.h \ ++ protocol/extensions.cc \ ++ protocol/extensions.h \ ++ protocol/handshake.cc \ ++ protocol/handshake.h \ ++ protocol/handshake_encryption.cc \ ++ protocol/handshake_encryption.h \ ++ protocol/handshake_manager.cc \ ++ protocol/handshake_manager.h \ ++ protocol/initial_seed.cc \ ++ protocol/initial_seed.h \ ++ protocol/peer_chunks.h \ ++ protocol/peer_connection_base.cc \ ++ protocol/peer_connection_base.h \ ++ protocol/peer_connection_leech.cc \ ++ protocol/peer_connection_leech.h \ ++ protocol/peer_connection_metadata.cc \ ++ protocol/peer_connection_metadata.h \ ++ protocol/peer_factory.cc \ ++ protocol/peer_factory.h \ ++ protocol/protocol_base.h \ ++ protocol/request_list.cc \ ++ protocol/request_list.h \ ++ \ ++ tracker/tracker_dht.cc \ ++ tracker/tracker_dht.h \ ++ tracker/tracker_http.cc \ ++ tracker/tracker_http.h \ ++ tracker/tracker_udp.cc \ ++ tracker/tracker_udp.h \ ++ \ ++ utils/diffie_hellman.cc \ ++ utils/diffie_hellman.h \ ++ utils/instrumentation.cc \ ++ utils/instrumentation.h \ ++ utils/rc4.h \ ++ utils/sha1.h \ ++ utils/sha_fast.cc \ ++ utils/sha_fast.h \ ++ utils/queue_buckets.h ++ + AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) +diff --git a/src/data/Makefile.am b/src/data/Makefile.am +deleted file mode 100644 +index ef41c9bd..00000000 +--- a/src/data/Makefile.am ++++ /dev/null +@@ -1,28 +0,0 @@ +-noinst_LTLIBRARIES = libsub_data.la +- +-libsub_data_la_SOURCES = \ +- chunk.cc \ +- chunk.h \ +- chunk_handle.h \ +- chunk_iterator.h \ +- chunk_list.cc \ +- chunk_list.h \ +- chunk_list_node.h \ +- chunk_part.cc \ +- chunk_part.h \ +- hash_check_queue.cc \ +- hash_check_queue.h \ +- hash_chunk.cc \ +- hash_chunk.h \ +- hash_queue.cc \ +- hash_queue.h \ +- hash_queue_node.cc \ +- hash_queue_node.h \ +- hash_torrent.cc \ +- hash_torrent.h \ +- memory_chunk.cc \ +- memory_chunk.h \ +- socket_file.cc \ +- socket_file.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am +deleted file mode 100644 +index a87c57bc..00000000 +--- a/src/dht/Makefile.am ++++ /dev/null +@@ -1,18 +0,0 @@ +-noinst_LTLIBRARIES = libsub_dht.la +- +-libsub_dht_la_SOURCES = \ +- dht_bucket.cc \ +- dht_bucket.h \ +- dht_hash_map.h \ +- dht_node.cc \ +- dht_node.h \ +- dht_router.cc \ +- dht_router.h \ +- dht_server.cc \ +- dht_server.h \ +- dht_tracker.cc \ +- dht_tracker.h \ +- dht_transaction.cc \ +- dht_transaction.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/src/download/Makefile.am b/src/download/Makefile.am +deleted file mode 100644 +index 65ceaf97..00000000 +--- a/src/download/Makefile.am ++++ /dev/null +@@ -1,19 +0,0 @@ +-noinst_LTLIBRARIES = libsub_download.la +- +-libsub_download_la_SOURCES = \ +- available_list.cc \ +- available_list.h \ +- chunk_selector.cc \ +- chunk_selector.h \ +- chunk_statistics.cc \ +- chunk_statistics.h \ +- delegator.cc \ +- delegator.h \ +- download_constructor.cc \ +- download_constructor.h \ +- download_main.cc \ +- download_main.h \ +- download_wrapper.cc \ +- download_wrapper.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/src/net/Makefile.am b/src/net/Makefile.am +deleted file mode 100644 +index e3a8c7e1..00000000 +--- a/src/net/Makefile.am ++++ /dev/null +@@ -1,30 +0,0 @@ +-noinst_LTLIBRARIES = libsub_net.la +- +-libsub_net_la_SOURCES = \ +- address_list.cc \ +- address_list.h \ +- data_buffer.h \ +- local_addr.cc \ +- local_addr.h \ +- listen.cc \ +- listen.h \ +- protocol_buffer.h \ +- socket_base.cc \ +- socket_base.h \ +- socket_datagram.cc \ +- socket_datagram.h \ +- socket_fd.cc \ +- socket_fd.h \ +- socket_listen.cc \ +- socket_listen.h \ +- socket_set.cc \ +- socket_set.h \ +- socket_stream.cc \ +- socket_stream.h \ +- throttle_internal.cc \ +- throttle_internal.h \ +- throttle_list.cc \ +- throttle_list.h \ +- throttle_node.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/src/protocol/Makefile.am b/src/protocol/Makefile.am +deleted file mode 100644 +index 2e9aba7a..00000000 +--- a/src/protocol/Makefile.am ++++ /dev/null +@@ -1,28 +0,0 @@ +-noinst_LTLIBRARIES = libsub_protocol.la +- +-libsub_protocol_la_SOURCES = \ +- encryption_info.h \ +- extensions.cc \ +- extensions.h \ +- handshake.cc \ +- handshake.h \ +- handshake_encryption.cc \ +- handshake_encryption.h \ +- handshake_manager.cc \ +- handshake_manager.h \ +- initial_seed.cc \ +- initial_seed.h \ +- peer_chunks.h \ +- peer_connection_base.cc \ +- peer_connection_base.h \ +- peer_connection_leech.cc \ +- peer_connection_leech.h \ +- peer_connection_metadata.cc \ +- peer_connection_metadata.h \ +- peer_factory.cc \ +- peer_factory.h \ +- protocol_base.h \ +- request_list.cc \ +- request_list.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am +index 8cd26ce7..30157b95 100644 +--- a/src/torrent/Makefile.am ++++ b/src/torrent/Makefile.am +@@ -1,13 +1,89 @@ +-SUBDIRS = \ +- data \ +- download \ +- net \ +- peer \ +- utils ++noinst_LTLIBRARIES = libtorrent_torrent.la + +-noinst_LTLIBRARIES = libsub_torrent.la +- +-libsub_torrent_la_SOURCES = \ ++libtorrent_torrent_la_SOURCES = \ ++ data/block.cc \ ++ data/block.h \ ++ data/block_failed.h \ ++ data/block_list.cc \ ++ data/block_list.h \ ++ data/block_transfer.h \ ++ data/chunk_utils.cc \ ++ data/chunk_utils.h \ ++ data/download_data.cc \ ++ data/download_data.h \ ++ data/file.cc \ ++ data/file.h \ ++ data/file_list.cc \ ++ data/file_list.h \ ++ data/file_list_iterator.cc \ ++ data/file_list_iterator.h \ ++ data/file_manager.cc \ ++ data/file_manager.h \ ++ data/file_utils.cc \ ++ data/file_utils.h \ ++ data/piece.h \ ++ data/transfer_list.cc \ ++ data/transfer_list.h \ ++\ ++ download/choke_group.cc \ ++ download/choke_group.h \ ++ download/choke_queue.cc \ ++ download/choke_queue.h \ ++ download/download_manager.cc \ ++ download/download_manager.h \ ++ download/group_entry.h \ ++ download/resource_manager.cc \ ++ download/resource_manager.h \ ++\ ++ net/address_info.cc \ ++ net/address_info.h \ ++ net/fd.cc \ ++ net/fd.h \ ++ net/socket_address.cc \ ++ net/socket_address.h \ ++ net/socket_address_key.cc \ ++ net/socket_address_key.h \ ++ net/socket_event.cc \ ++ net/socket_event.h \ ++ net/types.h \ ++\ ++ peer/choke_status.h \ ++ peer/client_info.cc \ ++ peer/client_info.h \ ++ peer/client_list.cc \ ++ peer/client_list.h \ ++ peer/connection_list.cc \ ++ peer/connection_list.h \ ++ peer/peer.cc \ ++ peer/peer.h \ ++ peer/peer_info.cc \ ++ peer/peer_info.h \ ++ peer/peer_list.cc \ ++ peer/peer_list.h \ ++\ ++ utils/directory_events.cc \ ++ utils/directory_events.h \ ++ utils/extents.h \ ++ utils/log.cc \ ++ utils/log.h \ ++ utils/log_buffer.cc \ ++ utils/log_buffer.h \ ++ utils/option_strings.cc \ ++ utils/option_strings.h \ ++ utils/random.cc \ ++ utils/random.h \ ++ utils/ranges.h \ ++ utils/resume.cc \ ++ utils/resume.h \ ++ utils/signal_bitfield.cc \ ++ utils/signal_bitfield.h \ ++ utils/thread_base.cc \ ++ utils/thread_base.h \ ++ utils/thread_interrupt.cc \ ++ utils/thread_interrupt.h \ ++ utils/uri_parser.cc \ ++ utils/uri_parser.h \ ++\ + bitfield.cc \ + bitfield.h \ + chunk_manager.cc \ +@@ -61,8 +137,64 @@ libsub_torrent_la_SOURCES = \ + + AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) + +-libtorrentincludedir = $(includedir)/torrent +-libtorrentinclude_HEADERS = \ ++libtorrent_torrent_data_includedir = $(includedir)/torrent/data ++libtorrent_torrent_data_include_HEADERS = \ ++ data/block.h \ ++ data/block_list.h \ ++ data/block_transfer.h \ ++ data/chunk_utils.h \ ++ data/download_data.h \ ++ data/file.h \ ++ data/file_list.h \ ++ data/file_list_iterator.h \ ++ data/file_manager.h \ ++ data/file_utils.h \ ++ data/piece.h \ ++ data/transfer_list.h ++ ++libtorrent_torrent_download_includedir = $(includedir)/torrent/download ++libtorrent_torrent_download_include_HEADERS = \ ++ download/choke_group.h \ ++ download/choke_queue.h \ ++ download/download_manager.h \ ++ download/group_entry.h \ ++ download/resource_manager.h ++ ++libtorrent_torrent_net_includedir = $(includedir)/torrent/net ++libtorrent_torrent_net_include_HEADERS = \ ++ net/address_info.h \ ++ net/fd.h \ ++ net/socket_address.h \ ++ net/socket_address_key.h \ ++ net/socket_event.h \ ++ net/types.h ++ ++libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer ++libtorrent_torrent_peer_include_HEADERS = \ ++ peer/choke_status.h \ ++ peer/client_info.h \ ++ peer/client_list.h \ ++ peer/connection_list.h \ ++ peer/peer.h \ ++ peer/peer_info.h \ ++ peer/peer_list.h ++ ++libtorrent_torrent_utils_includedir = $(includedir)/torrent/utils ++libtorrent_torrent_utils_include_HEADERS = \ ++ utils/directory_events.h \ ++ utils/extents.h \ ++ utils/log.h \ ++ utils/log_buffer.h \ ++ utils/option_strings.h \ ++ utils/ranges.h \ ++ utils/resume.h \ ++ utils/signal_bitfield.h \ ++ utils/thread_base.h \ ++ utils/thread_interrupt.h \ ++ utils/uri_parser.h ++ ++libtorrent_torrent_includedir = $(includedir)/torrent ++libtorrent_torrent_include_HEADERS = \ + bitfield.h \ + chunk_manager.h \ + common.h \ +diff --git a/src/torrent/download/Makefile.am b/src/torrent/download/Makefile.am +deleted file mode 100644 +index f92c7aa4..00000000 +--- a/src/torrent/download/Makefile.am ++++ /dev/null +@@ -1,22 +0,0 @@ +-noinst_LTLIBRARIES = libsub_torrentdownload.la +- +-libsub_torrentdownload_la_SOURCES = \ +- choke_group.cc \ +- choke_group.h \ +- choke_queue.cc \ +- choke_queue.h \ +- download_manager.cc \ +- download_manager.h \ +- group_entry.h \ +- resource_manager.cc \ +- resource_manager.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir) +- +-libtorrentincludedir = $(includedir)/torrent/download +-libtorrentinclude_HEADERS = \ +- choke_group.h \ +- choke_queue.h \ +- download_manager.h \ +- group_entry.h \ +- resource_manager.h +diff --git a/src/torrent/net/Makefile.am b/src/torrent/net/Makefile.am +deleted file mode 100644 +index 35dd4774..00000000 +--- a/src/torrent/net/Makefile.am ++++ /dev/null +@@ -1,25 +0,0 @@ +-noinst_LTLIBRARIES = libsub_torrentnet.la +- +-libsub_torrentnet_la_SOURCES = \ +- address_info.cc \ +- address_info.h \ +- fd.cc \ +- fd.h \ +- socket_address.cc \ +- socket_address.h \ +- socket_address_key.cc \ +- socket_address_key.h \ +- socket_event.cc \ +- socket_event.h \ +- types.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir) +- +-libtorrentincludedir = $(includedir)/torrent/net +-libtorrentinclude_HEADERS = \ +- address_info.h \ +- fd.h \ +- socket_address.h \ +- socket_address_key.h \ +- socket_event.h \ +- types.h +diff --git a/src/torrent/peer/Makefile.am b/src/torrent/peer/Makefile.am +deleted file mode 100644 +index 1324e88a..00000000 +--- a/src/torrent/peer/Makefile.am ++++ /dev/null +@@ -1,28 +0,0 @@ +-noinst_LTLIBRARIES = libsub_torrentpeer.la +- +-libsub_torrentpeer_la_SOURCES = \ +- choke_status.h \ +- client_info.cc \ +- client_info.h \ +- client_list.cc \ +- client_list.h \ +- connection_list.cc \ +- connection_list.h \ +- peer.cc \ +- peer.h \ +- peer_info.cc \ +- peer_info.h \ +- peer_list.cc \ +- peer_list.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir) +- +-libtorrentincludedir = $(includedir)/torrent/peer +-libtorrentinclude_HEADERS = \ +- choke_status.h \ +- client_info.h \ +- client_list.h \ +- connection_list.h \ +- peer.h \ +- peer_info.h \ +- peer_list.h +diff --git a/src/torrent/utils/Makefile.am b/src/torrent/utils/Makefile.am +deleted file mode 100644 +index a48786c6..00000000 +--- a/src/torrent/utils/Makefile.am ++++ /dev/null +@@ -1,41 +0,0 @@ +-noinst_LTLIBRARIES = libsub_torrentutils.la +- +-libsub_torrentutils_la_SOURCES = \ +- directory_events.cc \ +- directory_events.h \ +- extents.h \ +- log.cc \ +- log.h \ +- log_buffer.cc \ +- log_buffer.h \ +- option_strings.cc \ +- option_strings.h \ +- random.cc \ +- random.h \ +- ranges.h \ +- resume.cc \ +- resume.h \ +- signal_bitfield.cc \ +- signal_bitfield.h \ +- thread_base.cc \ +- thread_base.h \ +- thread_interrupt.cc \ +- thread_interrupt.h \ +- uri_parser.cc \ +- uri_parser.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir) +- +-libtorrentincludedir = $(includedir)/torrent/utils +-libtorrentinclude_HEADERS = \ +- directory_events.h \ +- extents.h \ +- log.h \ +- log_buffer.h \ +- option_strings.h \ +- ranges.h \ +- resume.h \ +- signal_bitfield.h \ +- thread_base.h \ +- thread_interrupt.h \ +- uri_parser.h +diff --git a/src/tracker/Makefile.am b/src/tracker/Makefile.am +deleted file mode 100644 +index 2f1ae5cf..00000000 +--- a/src/tracker/Makefile.am ++++ /dev/null +@@ -1,11 +0,0 @@ +-noinst_LTLIBRARIES = libsub_tracker.la +- +-libsub_tracker_la_SOURCES = \ +- tracker_dht.cc \ +- tracker_dht.h \ +- tracker_http.cc \ +- tracker_http.h \ +- tracker_udp.cc \ +- tracker_udp.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am +deleted file mode 100644 +index 27ce359b..00000000 +--- a/src/utils/Makefile.am ++++ /dev/null +@@ -1,14 +0,0 @@ +-noinst_LTLIBRARIES = libsub_utils.la +- +-libsub_utils_la_SOURCES = \ +- diffie_hellman.cc \ +- diffie_hellman.h \ +- instrumentation.cc \ +- instrumentation.h \ +- rc4.h \ +- sha1.h \ +- sha_fast.cc \ +- sha_fast.h \ +- queue_buckets.h +- +-AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir) +diff --git a/test/Makefile.am b/test/Makefile.am +index 23b260e4..8b0291bb 100644 +--- a/test/Makefile.am ++++ b/test/Makefile.am +@@ -1,25 +1,68 @@ +-SUBDIRS = torrent/net net +- +-TESTS = LibTorrentTest +-AUTOMAKE_OPTIONS = subdir-objects ++TESTS = \ ++ LibTorrent_Test_Torrent_Net \ ++ LibTorrent_Test_Net \ ++ LibTorrent_Test + + check_PROGRAMS = $(TESTS) +-LibTorrentTest_LDADD = \ ++ ++LibTorrent_Test_LDADD = \ + ../src/libtorrent.la \ +- ../src/torrent/libsub_torrent.la \ +- ../src/torrent/data/libsub_torrentdata.la \ +- ../src/torrent/download/libsub_torrentdownload.la \ +- ../src/torrent/peer/libsub_torrentpeer.la \ +- ../src/data/libsub_data.la \ +- ../src/dht/libsub_dht.la \ +- ../src/net/libsub_net.la \ +- ../src/protocol/libsub_protocol.la \ +- ../src/download/libsub_download.la \ +- ../src/tracker/libsub_tracker.la \ +- ../src/utils/libsub_utils.la \ +- ../src/torrent/utils/libsub_torrentutils.la ++ ../src/libtorrent_other.la \ ++ ../src/torrent/libtorrent_torrent.la ++ ++LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD) ++LibTorrent_Test_Torrent_Net_LDADD = $(LibTorrent_Test_LDADD) ++ ++# LibTorrent_Test_SOURCES = \ ++# helpers/expect_fd.h \ ++# helpers/expect_utils.h \ ++# helpers/mock_compare.h \ ++# helpers/mock_function.cc \ ++# helpers/mock_function.h \ ++# helpers/network.h \ ++# helpers/progress_listener.cc \ ++# helpers/progress_listener.h \ ++# helpers/test_fixture.cc \ ++# helpers/test_fixture.h ++ ++LibTorrent_Test_Torrent_Net_SOURCES = \ ++ main.cc \ ++ helpers/expect_fd.h \ ++ helpers/expect_utils.h \ ++ helpers/mock_compare.h \ ++ helpers/mock_function.cc \ ++ helpers/mock_function.h \ ++ helpers/network.h \ ++ helpers/progress_listener.cc \ ++ helpers/progress_listener.h \ ++ helpers/test_fixture.cc \ ++ helpers/test_fixture.h \ ++ \ ++ torrent/net/test_address_info.cc \ ++ torrent/net/test_address_info.h \ ++ torrent/net/test_fd.cc \ ++ torrent/net/test_fd.h \ ++ torrent/net/test_socket_address.cc \ ++ torrent/net/test_socket_address.h + +-LibTorrentTest_SOURCES = \ ++LibTorrent_Test_Net_SOURCES = \ ++ main.cc \ ++ helpers/expect_fd.h \ ++ helpers/expect_utils.h \ ++ helpers/mock_compare.h \ ++ helpers/mock_function.cc \ ++ helpers/mock_function.h \ ++ helpers/network.h \ ++ helpers/progress_listener.cc \ ++ helpers/progress_listener.h \ ++ helpers/test_fixture.cc \ ++ helpers/test_fixture.h \ ++ \ ++ net/test_socket_listen.cc \ ++ net/test_socket_listen.h ++ ++LibTorrent_Test_SOURCES = \ ++ main.cc \ + helpers/expect_fd.h \ + helpers/expect_utils.h \ + helpers/mock_compare.h \ +@@ -87,12 +130,15 @@ LibTorrentTest_SOURCES = \ + torrent/tracker_list_features_test.h \ + torrent/tracker_timeout_test.cc \ + torrent/tracker_timeout_test.h \ +- tracker/tracker_http_test.cc \ +- tracker/tracker_http_test.h \ + \ +- main.cc ++ tracker/tracker_http_test.cc \ ++ tracker/tracker_http_test.h + +-LibTorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS) +-LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_Torrent_Net_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_Torrent_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_Net_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_LDFLAGS = $(CPPUNIT_LIBS) -ldl + + AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src 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 000000000..4c7a2038f --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch @@ -0,0 +1,2710 @@ +From 9cdb950c0db2bad1a4d85b48f06419e2920aa114 Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Fri, 20 Dec 2019 00:37:38 +0900 +Subject: [PATCH] Refactor make process. (#207) + +--- + configure.ac | 3 +- + src/Makefile.am | 3 +- + src/manager.h | 36 --- + src/thread_disk.h | 51 +--- + src/torrent/utils/thread_base.cc | 36 --- + src/torrent/utils/thread_base.h | 48 +--- + test/Makefile.am | 140 +++++------ + ...{chunk_list_test.cc => test_chunk_list.cc} | 16 +- + .../{chunk_list_test.h => test_chunk_list.h} | 13 +- + ...queue_test.cc => test_hash_check_queue.cc} | 33 ++- + ...k_queue_test.h => test_hash_check_queue.h} | 22 +- + ...{hash_queue_test.cc => test_hash_queue.cc} | 66 +++--- + .../{hash_queue_test.h => test_hash_queue.h} | 11 +- + test/helpers/progress_listener.cc | 4 +- + test/helpers/test_fixture.h | 28 +-- + test/helpers/test_thread.cc | 71 ++++++ + test/helpers/test_thread.h | 59 +++++ + test/helpers/test_utils.h | 16 ++ + test/helpers/utils.h | 120 +++++----- + test/main.cc | 4 +- + test/torrent/{http_test.cc => test_http.cc} | 17 +- + test/torrent/{http_test.h => test_http.h} | 11 +- + test/torrent/utils/option_strings_test.h | 17 -- + test/torrent/utils/signal_bitfield_test.h | 23 -- + test/torrent/utils/test_extents.cc | 63 ++--- + test/torrent/utils/test_extents.h | 9 +- + .../utils/{log_test.cc => test_log.cc} | 26 +- + test/torrent/utils/{log_test.h => test_log.h} | 8 +- + test/torrent/utils/test_log_buffer.cc | 11 +- + test/torrent/utils/test_log_buffer.h | 5 - + ...strings_test.cc => test_option_strings.cc} | 29 +-- + test/torrent/utils/test_option_strings.h | 10 + + test/torrent/utils/test_queue_buckets.cc | 12 +- + test/torrent/utils/test_queue_buckets.h | 11 +- + ...tfield_test.cc => test_signal_bitfield.cc} | 31 ++- + test/torrent/utils/test_signal_bitfield.h | 22 ++ + test/torrent/utils/test_thread_base.cc | 169 +++++++++++++ + test/torrent/utils/test_thread_base.h | 25 ++ + test/torrent/utils/test_uri_parser.cc | 31 +-- + test/torrent/utils/test_uri_parser.h | 11 +- + test/torrent/utils/thread_base_test.cc | 224 ------------------ + test/torrent/utils/thread_base_test.h | 86 ------- + test/tracker/test_tracker_http.cc | 11 + + test/tracker/test_tracker_http.h | 12 + + test/tracker/tracker_http_test.cc | 17 -- + test/tracker/tracker_http_test.h | 18 -- + 46 files changed, 735 insertions(+), 954 deletions(-) + rename test/data/{chunk_list_test.cc => test_chunk_list.cc} (93%) + rename test/data/{chunk_list_test.h => test_chunk_list.h} (88%) + rename test/data/{hash_check_queue_test.cc => test_hash_check_queue.cc} (92%) + rename test/data/{hash_check_queue_test.h => test_hash_check_queue.h} (63%) + rename test/data/{hash_queue_test.cc => test_hash_queue.cc} (82%) + rename test/data/{hash_queue_test.h => test_hash_queue.h} (58%) + create mode 100755 test/helpers/test_thread.cc + create mode 100755 test/helpers/test_thread.h + create mode 100644 test/helpers/test_utils.h + rename test/torrent/{http_test.cc => test_http.cc} (94%) + rename test/torrent/{http_test.h => test_http.h} (63%) + delete mode 100644 test/torrent/utils/option_strings_test.h + delete mode 100644 test/torrent/utils/signal_bitfield_test.h + rename test/torrent/utils/{log_test.cc => test_log.cc} (92%) + rename test/torrent/utils/{log_test.h => test_log.h} (71%) + rename test/torrent/utils/{option_strings_test.cc => test_option_strings.cc} (65%) + create mode 100644 test/torrent/utils/test_option_strings.h + rename test/torrent/utils/{signal_bitfield_test.cc => test_signal_bitfield.cc} (85%) + create mode 100644 test/torrent/utils/test_signal_bitfield.h + create mode 100644 test/torrent/utils/test_thread_base.cc + create mode 100644 test/torrent/utils/test_thread_base.h + delete mode 100644 test/torrent/utils/thread_base_test.cc + delete mode 100644 test/torrent/utils/thread_base_test.h + create mode 100644 test/tracker/test_tracker_http.cc + create mode 100644 test/tracker/test_tracker_http.h + delete mode 100644 test/tracker/tracker_http_test.cc + delete mode 100644 test/tracker/tracker_http_test.h + +diff --git a/configure.ac b/configure.ac +index e83710cc..88a46edd 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -21,6 +21,7 @@ AM_INIT_AUTOMAKE([serial-tests subdir-objects]) + AC_CONFIG_HEADERS(config.h) + + AC_PROG_CXX ++AC_SYS_LARGEFILE + + AC_C_BIGENDIAN( + AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian), +@@ -37,8 +38,6 @@ RAK_DISABLE_BACKTRACE + + RAK_CHECK_CXX11 + +-AC_SYS_LARGEFILE +- + TORRENT_ENABLE_ALIGNED + TORRENT_ENABLE_INTERRUPT_SOCKET + +diff --git a/src/Makefile.am b/src/Makefile.am +index e96bd74b..95e6a7ae 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,7 +1,8 @@ + SUBDIRS = torrent + + lib_LTLIBRARIES = libtorrent.la +-noinst_LTLIBRARIES = libtorrent_other.la ++noinst_LTLIBRARIES = \ ++ libtorrent_other.la + + libtorrent_la_LDFLAGS = -version-info $(LIBTORRENT_INTERFACE_VERSION_INFO) + libtorrent_la_LIBADD = \ +diff --git a/src/manager.h b/src/manager.h +index 1db81e9b..1ada9567 100644 +--- a/src/manager.h ++++ b/src/manager.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_MANAGER_H + #define LIBTORRENT_MANAGER_H + +diff --git a/src/thread_disk.h b/src/thread_disk.h +index fa1fcb7e..7b378915 100644 +--- a/src/thread_disk.h ++++ b/src/thread_disk.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_THREAD_DISK_H + #define LIBTORRENT_THREAD_DISK_H + +@@ -42,19 +6,18 @@ + + namespace torrent { + +-class thread_disk : public thread_base { ++class LIBTORRENT_EXPORT thread_disk : public thread_base { + public: +- const char* name() const { return "rtorrent disk"; } +- +- virtual void init_thread(); ++ const char* name() const { return "rtorrent disk"; } ++ HashCheckQueue* hash_queue() { return &m_hash_queue; } + +- HashCheckQueue* hash_queue() { return &m_hash_queue; } ++ virtual void init_thread(); + + protected: +- virtual void call_events(); +- virtual int64_t next_timeout_usec(); ++ virtual void call_events(); ++ virtual int64_t next_timeout_usec(); + +- HashCheckQueue m_hash_queue; ++ HashCheckQueue m_hash_queue; + }; + + } +diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc +index 778e4c38..99d6355d 100644 +--- a/src/torrent/utils/thread_base.cc ++++ b/src/torrent/utils/thread_base.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +diff --git a/src/torrent/utils/thread_base.h b/src/torrent/utils/thread_base.h +index b92a98ba..bead9659 100644 +--- a/src/torrent/utils/thread_base.h ++++ b/src/torrent/utils/thread_base.h +@@ -1,48 +1,12 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_UTILS_THREAD_BASE_H + #define LIBTORRENT_UTILS_THREAD_BASE_H + +-#include +-#include +-#include ++#import ++#import ++#import + +-#include +-#include ++#import ++#import + + namespace torrent { + +@@ -54,7 +18,7 @@ public: + typedef void* (*pthread_func)(void*); + typedef std::function slot_void; + typedef std::function slot_timer; +- typedef class signal_bitfield signal_type; ++ typedef class signal_bitfield signal_type; + + enum state_type { + STATE_UNKNOWN, +diff --git a/test/Makefile.am b/test/Makefile.am +index 8b0291bb..cb00dce3 100644 +--- a/test/Makefile.am ++++ b/test/Makefile.am +@@ -1,6 +1,10 @@ + TESTS = \ + LibTorrent_Test_Torrent_Net \ ++ LibTorrent_Test_Torrent_Utils \ ++ LibTorrent_Test_Torrent \ ++ LibTorrent_Test_Data \ + LibTorrent_Test_Net \ ++ LibTorrent_Test_Tracker \ + LibTorrent_Test + + check_PROGRAMS = $(TESTS) +@@ -10,22 +14,14 @@ LibTorrent_Test_LDADD = \ + ../src/libtorrent_other.la \ + ../src/torrent/libtorrent_torrent.la + +-LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD) + LibTorrent_Test_Torrent_Net_LDADD = $(LibTorrent_Test_LDADD) ++LibTorrent_Test_Torrent_Utils_LDADD = $(LibTorrent_Test_LDADD) ++LibTorrent_Test_Torrent_LDADD = $(LibTorrent_Test_LDADD) ++LibTorrent_Test_Data_LDADD = $(LibTorrent_Test_LDADD) ++LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD) ++LibTorrent_Test_Tracker_LDADD = $(LibTorrent_Test_LDADD) + +-# LibTorrent_Test_SOURCES = \ +-# helpers/expect_fd.h \ +-# helpers/expect_utils.h \ +-# helpers/mock_compare.h \ +-# helpers/mock_function.cc \ +-# helpers/mock_function.h \ +-# helpers/network.h \ +-# helpers/progress_listener.cc \ +-# helpers/progress_listener.h \ +-# helpers/test_fixture.cc \ +-# helpers/test_fixture.h +- +-LibTorrent_Test_Torrent_Net_SOURCES = \ ++LibTorrent_Test_Common = \ + main.cc \ + helpers/expect_fd.h \ + helpers/expect_utils.h \ +@@ -37,7 +33,10 @@ LibTorrent_Test_Torrent_Net_SOURCES = \ + helpers/progress_listener.h \ + helpers/test_fixture.cc \ + helpers/test_fixture.h \ +- \ ++ helpers/test_thread.cc \ ++ helpers/test_thread.h ++ ++LibTorrent_Test_Torrent_Net_SOURCES = $(LibTorrent_Test_Common) \ + torrent/net/test_address_info.cc \ + torrent/net/test_address_info.h \ + torrent/net/test_fd.cc \ +@@ -45,71 +44,28 @@ LibTorrent_Test_Torrent_Net_SOURCES = \ + torrent/net/test_socket_address.cc \ + torrent/net/test_socket_address.h + +-LibTorrent_Test_Net_SOURCES = \ +- main.cc \ +- helpers/expect_fd.h \ +- helpers/expect_utils.h \ +- helpers/mock_compare.h \ +- helpers/mock_function.cc \ +- helpers/mock_function.h \ +- helpers/network.h \ +- helpers/progress_listener.cc \ +- helpers/progress_listener.h \ +- helpers/test_fixture.cc \ +- helpers/test_fixture.h \ +- \ +- net/test_socket_listen.cc \ +- net/test_socket_listen.h +- +-LibTorrent_Test_SOURCES = \ +- main.cc \ +- helpers/expect_fd.h \ +- helpers/expect_utils.h \ +- helpers/mock_compare.h \ +- helpers/mock_function.cc \ +- helpers/mock_function.h \ +- helpers/network.h \ +- helpers/progress_listener.cc \ +- helpers/progress_listener.h \ +- helpers/test_fixture.cc \ +- helpers/test_fixture.h \ +- \ +- ../src/thread_disk.cc \ +- ../src/thread_disk.h \ +- \ +- rak/allocators_test.cc \ +- rak/allocators_test.h \ +- rak/ranges_test.cc \ +- rak/ranges_test.h \ +- data/chunk_list_test.cc \ +- data/chunk_list_test.h \ +- data/hash_check_queue_test.cc \ +- data/hash_check_queue_test.h \ +- data/hash_queue_test.cc \ +- data/hash_queue_test.h \ +- \ +- protocol/test_request_list.cc \ +- protocol/test_request_list.h \ +- \ +- torrent/utils/log_test.cc \ +- torrent/utils/log_test.h \ +- torrent/utils/option_strings_test.cc \ +- torrent/utils/option_strings_test.h \ ++LibTorrent_Test_Torrent_Utils_SOURCES = $(LibTorrent_Test_Common) \ + torrent/utils/test_extents.cc \ + torrent/utils/test_extents.h \ ++ torrent/utils/test_log.cc \ ++ torrent/utils/test_log.h \ + torrent/utils/test_log_buffer.cc \ + torrent/utils/test_log_buffer.h \ ++ torrent/utils/test_option_strings.cc \ ++ torrent/utils/test_option_strings.h \ + torrent/utils/test_queue_buckets.cc \ + torrent/utils/test_queue_buckets.h \ ++ torrent/utils/test_signal_bitfield.cc \ ++ torrent/utils/test_signal_bitfield.h \ ++ torrent/utils/test_thread_base.cc \ ++ torrent/utils/test_thread_base.h \ + torrent/utils/test_uri_parser.cc \ +- torrent/utils/test_uri_parser.h \ +- torrent/utils/signal_bitfield_test.cc \ +- torrent/utils/signal_bitfield_test.h \ +- torrent/utils/thread_base_test.cc \ +- torrent/utils/thread_base_test.h \ ++ torrent/utils/test_uri_parser.h ++ ++LibTorrent_Test_Torrent_SOURCES = $(LibTorrent_Test_Common) \ ++ torrent/test_http.cc \ ++ torrent/test_http.h \ + \ +- torrent/http_test.cc \ +- torrent/http_test.h \ + torrent/object_test.cc \ + torrent/object_test.h \ + torrent/object_test_utils.cc \ +@@ -129,15 +85,49 @@ LibTorrent_Test_SOURCES = \ + torrent/tracker_list_features_test.cc \ + torrent/tracker_list_features_test.h \ + torrent/tracker_timeout_test.cc \ +- torrent/tracker_timeout_test.h \ ++ torrent/tracker_timeout_test.h ++ ++LibTorrent_Test_Data_SOURCES = $(LibTorrent_Test_Common) \ ++ data/test_chunk_list.cc \ ++ data/test_chunk_list.h \ ++ data/test_hash_check_queue.cc \ ++ data/test_hash_check_queue.h \ ++ data/test_hash_queue.cc \ ++ data/test_hash_queue.h ++ ++LibTorrent_Test_Net_SOURCES = $(LibTorrent_Test_Common) \ ++ net/test_socket_listen.cc \ ++ net/test_socket_listen.h ++ ++LibTorrent_Test_Tracker_SOURCES = $(LibTorrent_Test_Common) \ ++ tracker/test_tracker_http.cc \ ++ tracker/test_tracker_http.h ++ ++LibTorrent_Test_SOURCES = $(LibTorrent_Test_Common) \ ++ \ ++ ../src/thread_disk.cc \ ++ ../src/thread_disk.h \ + \ +- tracker/tracker_http_test.cc \ +- tracker/tracker_http_test.h ++ rak/allocators_test.cc \ ++ rak/allocators_test.h \ ++ rak/ranges_test.cc \ ++ rak/ranges_test.h \ ++ \ ++ protocol/test_request_list.cc \ ++ protocol/test_request_list.h + + LibTorrent_Test_Torrent_Net_CXXFLAGS = $(CPPUNIT_CFLAGS) + LibTorrent_Test_Torrent_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_Torrent_Utils_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_Torrent_Utils_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_Torrent_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_Torrent_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_Data_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_Data_LDFLAGS = $(CPPUNIT_LIBS) -ldl + LibTorrent_Test_Net_CXXFLAGS = $(CPPUNIT_CFLAGS) + LibTorrent_Test_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl ++LibTorrent_Test_Tracker_CXXFLAGS = $(CPPUNIT_CFLAGS) ++LibTorrent_Test_Tracker_LDFLAGS = $(CPPUNIT_LIBS) -ldl + LibTorrent_Test_CXXFLAGS = $(CPPUNIT_CFLAGS) + LibTorrent_Test_LDFLAGS = $(CPPUNIT_LIBS) -ldl + +diff --git a/test/data/chunk_list_test.cc b/test/data/test_chunk_list.cc +similarity index 93% +rename from test/data/chunk_list_test.cc +rename to test/data/test_chunk_list.cc +index 28647db2..18de597e 100644 +--- a/test/data/chunk_list_test.cc ++++ b/test/data/test_chunk_list.cc +@@ -1,11 +1,11 @@ +-#include "config.h" ++#import "config.h" + +-#include "chunk_list_test.h" ++#import "test_chunk_list.h" + +-#include "torrent/chunk_manager.h" +-#include "torrent/exceptions.h" ++#import "torrent/chunk_manager.h" ++#import "torrent/exceptions.h" + +-CPPUNIT_TEST_SUITE_REGISTRATION(ChunkListTest); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_chunk_list, "data"); + + torrent::Chunk* + func_create_chunk(uint32_t index, int prot_flags) { +@@ -36,7 +36,7 @@ func_storage_error(torrent::ChunkList* chunk_list, const std::string& message) { + } + + void +-ChunkListTest::test_basic() { ++test_chunk_list::test_basic() { + torrent::ChunkManager chunk_manager; + torrent::ChunkList chunk_list; + +@@ -55,7 +55,7 @@ ChunkListTest::test_basic() { + } + + void +-ChunkListTest::test_get_release() { ++test_chunk_list::test_get_release() { + SETUP_CHUNK_LIST(); + + CPPUNIT_ASSERT(!(*chunk_list)[0].is_valid()); +@@ -112,7 +112,7 @@ ChunkListTest::test_get_release() { + + // Make sure we can't go into writable when blocking, etc. + void +-ChunkListTest::test_blocking() { ++test_chunk_list::test_blocking() { + SETUP_CHUNK_LIST(); + + torrent::ChunkHandle handle_0_ro = chunk_list->get(0, torrent::ChunkList::get_blocking); +diff --git a/test/data/chunk_list_test.h b/test/data/test_chunk_list.h +similarity index 88% +rename from test/data/chunk_list_test.h +rename to test/data/test_chunk_list.h +index 3979982f..85d1f77b 100644 +--- a/test/data/chunk_list_test.h ++++ b/test/data/test_chunk_list.h +@@ -1,23 +1,22 @@ +-#include ++#import "helpers/test_fixture.h" + +-#include "data/chunk_list.h" ++class test_chunk_list : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_chunk_list); + +-class ChunkListTest : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(ChunkListTest); + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_get_release); + CPPUNIT_TEST(test_blocking); ++ + CPPUNIT_TEST_SUITE_END(); + + public: +- void setUp() {} +- void tearDown() {} +- + void test_basic(); + void test_get_release(); + void test_blocking(); + }; + ++#include "data/chunk_list.h" ++ + torrent::Chunk* func_create_chunk(uint32_t index, int prot_flags); + uint64_t func_free_diskspace(torrent::ChunkList* chunk_list); + void func_storage_error(torrent::ChunkList* chunk_list, const std::string& message); +diff --git a/test/data/hash_check_queue_test.cc b/test/data/test_hash_check_queue.cc +similarity index 92% +rename from test/data/hash_check_queue_test.cc +rename to test/data/test_hash_check_queue.cc +index 4b15245e..65931273 100644 +--- a/test/data/hash_check_queue_test.cc ++++ b/test/data/test_hash_check_queue.cc +@@ -1,20 +1,23 @@ + #include "config.h" + ++#include "test_hash_check_queue.h" ++ ++#include "helpers/test_thread.h" ++#include "helpers/test_utils.h" ++ + #include + #include + +-#include "data/hash_queue_node.h" ++#include "data/chunk_handle.h" + #include "utils/sha1.h" + #include "torrent/chunk_manager.h" + #include "torrent/exceptions.h" + #include "torrent/poll_select.h" +-#include "torrent/utils/thread_base_test.h" + #include "thread_disk.h" + +-#include "chunk_list_test.h" +-#include "hash_check_queue_test.h" ++#include "test_chunk_list.h" + +-CPPUNIT_TEST_SUITE_REGISTRATION(HashCheckQueueTest); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_hash_check_queue, "data"); + + pthread_mutex_t done_chunks_lock = PTHREAD_MUTEX_INITIALIZER; + +@@ -68,22 +71,16 @@ static torrent::Poll* create_select_poll() { return torrent::PollSelect::create( + static void do_nothing() {} + + void +-HashCheckQueueTest::setUp() { ++test_hash_check_queue::setUp() { ++ test_fixture::setUp(); ++ + torrent::Poll::slot_create_poll() = std::bind(&create_select_poll); + + signal(SIGUSR1, (sig_t)&do_nothing); + } + + void +-HashCheckQueueTest::tearDown() { +-} +- +-void +-HashCheckQueueTest::test_basic() { +-} +- +-void +-HashCheckQueueTest::test_single() { ++test_hash_check_queue::test_single() { + SETUP_CHUNK_LIST(); + torrent::HashCheckQueue hash_queue; + +@@ -110,7 +107,7 @@ HashCheckQueueTest::test_single() { + } + + void +-HashCheckQueueTest::test_multiple() { ++test_hash_check_queue::test_multiple() { + SETUP_CHUNK_LIST(); + torrent::HashCheckQueue hash_queue; + +@@ -143,7 +140,7 @@ HashCheckQueueTest::test_multiple() { + } + + void +-HashCheckQueueTest::test_erase() { ++test_hash_check_queue::test_erase() { + // SETUP_CHUNK_LIST(); + // torrent::HashCheckQueue hash_queue; + +@@ -176,7 +173,7 @@ HashCheckQueueTest::test_erase() { + } + + void +-HashCheckQueueTest::test_thread() { ++test_hash_check_queue::test_thread() { + SETUP_CHUNK_LIST(); + SETUP_THREAD(); + thread_disk->start_thread(); +diff --git a/test/data/hash_check_queue_test.h b/test/data/test_hash_check_queue.h +similarity index 63% +rename from test/data/hash_check_queue_test.h +rename to test/data/test_hash_check_queue.h +index 5398a50d..d2d271bb 100644 +--- a/test/data/hash_check_queue_test.h ++++ b/test/data/test_hash_check_queue.h +@@ -1,26 +1,19 @@ +-#include +-#include +-#include ++#import "helpers/test_fixture.h" + +-#include "data/hash_check_queue.h" +-#include "torrent/hash_string.h" ++class test_hash_check_queue : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_hash_check_queue); + +- +-class HashCheckQueueTest : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(HashCheckQueueTest); +- CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_single); + CPPUNIT_TEST(test_multiple); + CPPUNIT_TEST(test_erase); + + CPPUNIT_TEST(test_thread); ++ + CPPUNIT_TEST_SUITE_END(); + + public: + void setUp(); +- void tearDown(); + +- void test_basic(); + void test_single(); + void test_multiple(); + void test_erase(); +@@ -28,6 +21,13 @@ public: + void test_thread(); + }; + ++#import ++#import ++ ++#import "data/hash_queue_node.h" ++#import "data/hash_check_queue.h" ++#import "torrent/hash_string.h" ++ + typedef std::map done_chunks_type; + typedef std::vector handle_list; + +diff --git a/test/data/hash_queue_test.cc b/test/data/test_hash_queue.cc +similarity index 82% +rename from test/data/hash_queue_test.cc +rename to test/data/test_hash_queue.cc +index d7ce3ba8..d9a88c8d 100644 +--- a/test/data/hash_queue_test.cc ++++ b/test/data/test_hash_queue.cc +@@ -1,22 +1,26 @@ +-#include "config.h" ++#import "config.h" + +-#include +-#include ++#import "test_hash_queue.h" + +-#include "data/hash_queue_node.h" +-#include "torrent/chunk_manager.h" +-#include "torrent/exceptions.h" +-#include "torrent/hash_string.h" +-#include "torrent/poll_select.h" +-#include "torrent/utils/thread_base_test.h" +-#include "globals.h" +-#include "thread_disk.h" ++#import "helpers/test_thread.h" ++#import "helpers/test_utils.h" + +-#include "chunk_list_test.h" +-#include "hash_queue_test.h" +-#include "hash_check_queue_test.h" ++#import ++#import + +-CPPUNIT_TEST_SUITE_REGISTRATION(HashQueueTest); ++#import "data/hash_queue.h" ++#import "data/hash_queue_node.h" ++#import "torrent/chunk_manager.h" ++#import "torrent/exceptions.h" ++#import "torrent/hash_string.h" ++#import "torrent/poll_select.h" ++#import "globals.h" ++#import "thread_disk.h" ++ ++#import "test_chunk_list.h" ++#import "test_hash_check_queue.h" ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_hash_queue, "data"); + + typedef std::map done_chunks_type; + +@@ -39,7 +43,9 @@ static torrent::Poll* create_select_poll() { return torrent::PollSelect::create( + static void do_nothing() {} + + void +-HashQueueTest::setUp() { ++test_hash_queue::setUp() { ++ test_fixture::setUp(); ++ + CPPUNIT_ASSERT(torrent::taskScheduler.empty()); + + torrent::Poll::slot_create_poll() = std::bind(&create_select_poll); +@@ -47,25 +53,9 @@ HashQueueTest::setUp() { + } + + void +-HashQueueTest::tearDown() { ++test_hash_queue::tearDown() { + torrent::taskScheduler.clear(); +-} +- +-void +-HashQueueTest::test_basic() { +- // SETUP_CHUNK_LIST(); +- // SETUP_THREAD(); +- // thread_disk->start_thread(); +- +- // torrent::HashQueue* hash_queue = new torrent::HashQueue(thread_disk); +- +- // // Do stuff? +- +- // delete hash_queue; +- +- // thread_disk->stop_thread(); +- // CLEANUP_THREAD(); +- // CLEANUP_CHUNK_LIST(); ++ test_fixture::tearDown(); + } + + static void +@@ -73,7 +63,7 @@ fill_queue() { + } + + void +-HashQueueTest::test_single() { ++test_hash_queue::test_single() { + SETUP_CHUNK_LIST(); + SETUP_THREAD(); + thread_disk->start_thread(); +@@ -105,7 +95,7 @@ HashQueueTest::test_single() { + } + + void +-HashQueueTest::test_multiple() { ++test_hash_queue::test_multiple() { + SETUP_CHUNK_LIST(); + SETUP_THREAD(); + thread_disk->start_thread(); +@@ -137,7 +127,7 @@ HashQueueTest::test_multiple() { + } + + void +-HashQueueTest::test_erase() { ++test_hash_queue::test_erase() { + SETUP_CHUNK_LIST(); + SETUP_THREAD(); + +@@ -164,7 +154,7 @@ HashQueueTest::test_erase() { + } + + void +-HashQueueTest::test_erase_stress() { ++test_hash_queue::test_erase_stress() { + SETUP_CHUNK_LIST(); + SETUP_THREAD(); + thread_disk->start_thread(); +diff --git a/test/data/hash_queue_test.h b/test/data/test_hash_queue.h +similarity index 58% +rename from test/data/hash_queue_test.h +rename to test/data/test_hash_queue.h +index cb5b7282..79914484 100644 +--- a/test/data/hash_queue_test.h ++++ b/test/data/test_hash_queue.h +@@ -1,10 +1,7 @@ +-#include ++#include "helpers/test_fixture.h" + +-#include "data/hash_queue.h" +- +-class HashQueueTest : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(HashQueueTest); +- CPPUNIT_TEST(test_basic); ++class test_hash_queue : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_hash_queue); + + CPPUNIT_TEST(test_single); + CPPUNIT_TEST(test_multiple); +@@ -17,8 +14,6 @@ public: + void setUp(); + void tearDown(); + +- void test_basic(); +- + void test_single(); + void test_multiple(); + void test_erase(); +diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc +index c2b60bcd..7a6ed047 100644 +--- a/test/helpers/progress_listener.cc ++++ b/test/helpers/progress_listener.cc +@@ -36,10 +36,10 @@ progress_listener::addFailure(const CppUnit::TestFailure &failure) { + if (m_current_log_buffer == nullptr) + return; + +- std::cout << " : " << (failure.isError() ? "error" : "assertion"); ++ std::cout << " : " << (failure.isError() ? "error" : "assertion") << std::flush; + + m_last_test_failed = true; +- m_failures.push_back(std::move(failure_type{failure.failedTestName(), std::move(m_current_log_buffer)})); ++ m_failures.push_back(failure_type{ failure.failedTestName(), std::move(m_current_log_buffer) }); + } + + void +diff --git a/test/helpers/test_fixture.h b/test/helpers/test_fixture.h +index 312d5009..aa557a5e 100644 +--- a/test/helpers/test_fixture.h ++++ b/test/helpers/test_fixture.h +@@ -1,14 +1,14 @@ +-#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H +-#define LIBTORRENT_HELPER_TEST_FIXTURE_H +- +-#include +- +-#include "helpers/mock_function.h" +- +-class test_fixture : public CppUnit::TestFixture { +-public: +- void setUp(); +- void tearDown(); +-}; +- +-#endif ++#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H ++#define LIBTORRENT_HELPER_TEST_FIXTURE_H ++ ++#include ++ ++#include "helpers/mock_function.h" ++ ++class test_fixture : public CppUnit::TestFixture { ++public: ++ void setUp(); ++ void tearDown(); ++}; ++ ++#endif +diff --git a/test/helpers/test_thread.cc b/test/helpers/test_thread.cc +new file mode 100755 +index 00000000..4b3d4c95 +--- /dev/null ++++ b/test/helpers/test_thread.cc +@@ -0,0 +1,71 @@ ++#import "config.h" ++ ++#import "test_thread.h" ++ ++#import ++#import ++ ++#import "thread_disk.h" ++#import "torrent/exceptions.h" ++#import "torrent/poll_select.h" ++ ++const int test_thread::test_flag_pre_stop; ++const int test_thread::test_flag_long_timeout; ++ ++const int test_thread::test_flag_acquire_global; ++const int test_thread::test_flag_has_global; ++ ++const int test_thread::test_flag_do_work; ++const int test_thread::test_flag_pre_poke; ++const int test_thread::test_flag_post_poke; ++ ++test_thread::test_thread() : ++ m_test_state(TEST_NONE), ++ m_test_flags(0) { ++} ++ ++void ++test_thread::init_thread() { ++ m_state = STATE_INITIALIZED; ++ m_test_state = TEST_PRE_START; ++ m_poll = torrent::PollSelect::create(256); ++} ++ ++void ++test_thread::call_events() { ++ if ((m_test_flags & test_flag_pre_stop) && m_test_state == TEST_PRE_START && m_state == STATE_ACTIVE) ++ __sync_lock_test_and_set(&m_test_state, TEST_PRE_STOP); ++ ++ if ((m_test_flags & test_flag_acquire_global)) { ++ acquire_global_lock(); ++ __sync_and_and_fetch(&m_test_flags, ~test_flag_acquire_global); ++ __sync_or_and_fetch(&m_test_flags, test_flag_has_global); ++ } ++ ++ if ((m_flags & flag_do_shutdown)) { ++ if ((m_flags & flag_did_shutdown)) ++ throw torrent::internal_error("Already trigged shutdown."); ++ ++ __sync_or_and_fetch(&m_flags, flag_did_shutdown); ++ throw torrent::shutdown_exception(); ++ } ++ ++ if ((m_test_flags & test_flag_pre_poke)) { ++ } ++ ++ if ((m_test_flags & test_flag_do_work)) { ++ usleep(10 * 1000); // TODO: Don't just sleep, as that give up core. ++ __sync_and_and_fetch(&m_test_flags, ~test_flag_do_work); ++ } ++ ++ if ((m_test_flags & test_flag_post_poke)) { ++ } ++} ++ ++thread_management_type::thread_management_type() { ++ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); ++} ++ ++thread_management_type::~thread_management_type() { ++ torrent::thread_base::release_global_lock(); ++} +diff --git a/test/helpers/test_thread.h b/test/helpers/test_thread.h +new file mode 100755 +index 00000000..52037036 +--- /dev/null ++++ b/test/helpers/test_thread.h +@@ -0,0 +1,59 @@ ++#import "torrent/utils/thread_base.h" ++ ++class test_thread : public torrent::thread_base { ++public: ++ enum test_state { ++ TEST_NONE, ++ TEST_PRE_START, ++ TEST_PRE_STOP, ++ TEST_STOP ++ }; ++ ++ static const int test_flag_pre_stop = 0x1; ++ static const int test_flag_long_timeout = 0x2; ++ ++ static const int test_flag_acquire_global = 0x10; ++ static const int test_flag_has_global = 0x20; ++ ++ static const int test_flag_do_work = 0x100; ++ static const int test_flag_pre_poke = 0x200; ++ static const int test_flag_post_poke = 0x400; ++ ++ test_thread(); ++ ++ int test_state() const { return m_test_state; } ++ bool is_state(int state) const { return m_state == state; } ++ bool is_test_state(int state) const { return m_test_state == state; } ++ bool is_test_flags(int flags) const { return (m_test_flags & flags) == flags; } ++ bool is_not_test_flags(int flags) const { return !(m_test_flags & flags); } ++ ++ auto name() const -> const char* { return "test_thread"; } ++ ++ void init_thread(); ++ ++ void set_pre_stop() { __sync_or_and_fetch(&m_test_flags, test_flag_pre_stop); } ++ void set_acquire_global() { __sync_or_and_fetch(&m_test_flags, test_flag_acquire_global); } ++ ++ void set_test_flag(int flags) { __sync_or_and_fetch(&m_test_flags, flags); } ++ ++private: ++ void call_events(); ++ int64_t next_timeout_usec() { return (m_test_flags & test_flag_long_timeout) ? (10000 * 1000) : (100 * 1000); } ++ ++ int m_test_state lt_cacheline_aligned; ++ int m_test_flags lt_cacheline_aligned; ++}; ++ ++struct thread_management_type { ++ thread_management_type(); ++ ~thread_management_type(); ++}; ++ ++#define SETUP_THREAD() \ ++ thread_management_type thread_management; \ ++ torrent::thread_disk* thread_disk = new torrent::thread_disk(); \ ++ thread_disk->init_thread(); ++ ++#define CLEANUP_THREAD() \ ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&torrent::thread_base::is_inactive, thread_disk))); \ ++ delete thread_disk; +diff --git a/test/helpers/test_utils.h b/test/helpers/test_utils.h +new file mode 100644 +index 00000000..0c8c6b7a +--- /dev/null ++++ b/test/helpers/test_utils.h +@@ -0,0 +1,16 @@ ++#include ++#include ++ ++inline bool ++wait_for_true(std::function test_function) { ++ int i = 100; ++ ++ do { ++ if (test_function()) ++ return true; ++ ++ usleep(10 * 1000); ++ } while (--i); ++ ++ return false; ++} +diff --git a/test/helpers/utils.h b/test/helpers/utils.h +index d18450c1..e81d22eb 100644 +--- a/test/helpers/utils.h ++++ b/test/helpers/utils.h +@@ -1,60 +1,60 @@ +-#ifndef LIBTORRENT_HELPER_UTILS_H +-#define LIBTORRENT_HELPER_UTILS_H +- +-#include +-#include +-#include +-#include +- +-static void +-dump_failure_log(const failure_type& failure) { +- if (failure.log->empty()) +- return; +- +- std::cout << std::endl << failure.name << std::endl; +- +- // Doesn't print dump messages as log_buffer drops them. +- std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) { +- std::cout << entry.timestamp << ' ' << entry.message << '\n'; +- }); +- +- std::cout << std::flush; +-} +- +-static void +-dump_failures(const failure_list_type& failures) { +- if (failures.empty()) +- return; +- +- std::cout << std::endl +- << "=================" << std::endl +- << "Failed Test Logs:" << std::endl +- << "=================" << std::endl; +- +- std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) { +- dump_failure_log(failure); +- }); +- std::cout << std::endl; +-} +- +-static +-void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) { +- if (c_test_names == NULL || std::string(c_test_names).empty()) { +- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); +- return; +- } +- +- const std::string& test_names(c_test_names); +- +- size_t pos = 0; +- size_t next = 0; +- +- while ((next = test_names.find(',', pos)) < test_names.size()) { +- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest()); +- pos = next + 1; +- } +- +- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest()); +-} +- +-#endif ++#ifndef LIBTORRENT_HELPER_UTILS_H ++#define LIBTORRENT_HELPER_UTILS_H ++ ++#include ++#include ++#include ++#include ++ ++static void ++dump_failure_log(const failure_type& failure) { ++ if (failure.log->empty()) ++ return; ++ ++ std::cout << std::endl << failure.name << std::endl; ++ ++ // Doesn't print dump messages as log_buffer drops them. ++ std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) { ++ std::cout << entry.timestamp << ' ' << entry.message << '\n'; ++ }); ++ ++ std::cout << std::flush; ++} ++ ++static void ++dump_failures(const failure_list_type& failures) { ++ if (failures.empty()) ++ return; ++ ++ std::cout << std::endl ++ << "=================" << std::endl ++ << "Failed Test Logs:" << std::endl ++ << "=================" << std::endl; ++ ++ std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) { ++ dump_failure_log(failure); ++ }); ++ std::cout << std::endl; ++} ++ ++static ++void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) { ++ if (c_test_names == NULL || std::string(c_test_names).empty()) { ++ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); ++ return; ++ } ++ ++ const std::string& test_names(c_test_names); ++ ++ size_t pos = 0; ++ size_t next = 0; ++ ++ while ((next = test_names.find(',', pos)) < test_names.size()) { ++ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest()); ++ pos = next + 1; ++ } ++ ++ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest()); ++} ++ ++#endif +diff --git a/test/main.cc b/test/main.cc +index e8a00e1f..57ae31a2 100644 +--- a/test/main.cc ++++ b/test/main.cc +@@ -19,9 +19,11 @@ + #include "helpers/progress_listener.h" + #include "helpers/utils.h" + +-CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net"); + CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/net"); + CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/utils"); ++CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent"); ++CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net"); ++CPPUNIT_REGISTRY_ADD_TO_DEFAULT("tracker"); + + void + do_test_panic(int signum) { +diff --git a/test/torrent/http_test.cc b/test/torrent/test_http.cc +similarity index 94% +rename from test/torrent/http_test.cc +rename to test/torrent/test_http.cc +index 27e04552..24ec97b5 100644 +--- a/test/torrent/http_test.cc ++++ b/test/torrent/test_http.cc +@@ -1,10 +1,11 @@ + #include "config.h" + +-#include ++#include "test_http.h" + +-#include "http_test.h" ++#include ++#include "torrent/http.h" + +-CPPUNIT_TEST_SUITE_REGISTRATION(HttpTest); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_http, "torrent"); + + #define HTTP_SETUP() \ + bool http_destroyed = false; \ +@@ -72,7 +73,7 @@ TestHttp* create_test_http() { return new TestHttp; } + static void increment_value(int* value) { (*value)++; } + + void +-HttpTest::test_basic() { ++test_http::test_basic() { + torrent::Http::slot_factory() = std::bind(&create_test_http); + + torrent::Http* http = torrent::Http::slot_factory()(); +@@ -94,7 +95,7 @@ HttpTest::test_basic() { + } + + void +-HttpTest::test_done() { ++test_http::test_done() { + HTTP_SETUP(); + http->start(); + +@@ -106,7 +107,7 @@ HttpTest::test_done() { + } + + void +-HttpTest::test_failure() { ++test_http::test_failure() { + HTTP_SETUP(); + http->start(); + +@@ -118,7 +119,7 @@ HttpTest::test_failure() { + } + + void +-HttpTest::test_delete_on_done() { ++test_http::test_delete_on_done() { + HTTP_SETUP(); + http->start(); + http->set_delete_stream(); +@@ -145,7 +146,7 @@ HttpTest::test_delete_on_done() { + } + + void +-HttpTest::test_delete_on_failure() { ++test_http::test_delete_on_failure() { + HTTP_SETUP(); + http->start(); + http->set_delete_stream(); +diff --git a/test/torrent/http_test.h b/test/torrent/test_http.h +similarity index 63% +rename from test/torrent/http_test.h +rename to test/torrent/test_http.h +index c6c97d08..f4334646 100644 +--- a/test/torrent/http_test.h ++++ b/test/torrent/test_http.h +@@ -1,21 +1,18 @@ +-#include ++#import "helpers/test_fixture.h" + +-#include "torrent/http.h" ++class test_http : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_http); + +-class HttpTest : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(HttpTest); + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_done); + CPPUNIT_TEST(test_failure); + + CPPUNIT_TEST(test_delete_on_done); + CPPUNIT_TEST(test_delete_on_failure); ++ + CPPUNIT_TEST_SUITE_END(); + + public: +- void setUp() {} +- void tearDown() {} +- + void test_basic(); + void test_done(); + void test_failure(); +diff --git a/test/torrent/utils/option_strings_test.h b/test/torrent/utils/option_strings_test.h +deleted file mode 100644 +index 55df4f19..00000000 +--- a/test/torrent/utils/option_strings_test.h ++++ /dev/null +@@ -1,17 +0,0 @@ +-#include +- +-#include "torrent/utils/option_strings.h" +- +-class option_strings_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(option_strings_test); +- CPPUNIT_TEST(test_basic); +- CPPUNIT_TEST(test_entries); +- CPPUNIT_TEST_SUITE_END(); +- +-public: +- void setUp() {} +- void tearDown() {} +- +- void test_basic(); +- void test_entries(); +-}; +diff --git a/test/torrent/utils/signal_bitfield_test.h b/test/torrent/utils/signal_bitfield_test.h +deleted file mode 100644 +index 4590de41..00000000 +--- a/test/torrent/utils/signal_bitfield_test.h ++++ /dev/null +@@ -1,23 +0,0 @@ +-#include +- +-#include "torrent/utils/signal_bitfield.h" +- +-class utils_signal_bitfield_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(utils_signal_bitfield_test); +- CPPUNIT_TEST(test_basic); +- CPPUNIT_TEST(test_single); +- CPPUNIT_TEST(test_multiple); +- +- CPPUNIT_TEST(test_thread); +- CPPUNIT_TEST_SUITE_END(); +- +-public: +- void setUp(); +- void tearDown(); +- +- void test_basic(); +- void test_single(); +- void test_multiple(); +- +- void test_thread(); +-}; +diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc +index 87424d62..8e614e10 100644 +--- a/test/torrent/utils/test_extents.cc ++++ b/test/torrent/utils/test_extents.cc +@@ -2,34 +2,25 @@ + + #include "test_extents.h" + +-#include +-#include + #include ++#include + +-CPPUNIT_TEST_SUITE_REGISTRATION(ExtentsTest); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_extents, "torrent/utils"); + +-void +-ExtentsTest::setUp() { +-} ++#define TEST_EXTENT_BEGIN(name) \ ++ lt_log_print(torrent::LOG_MOCK_CALLS, "extent: %s", name); + +-void +-ExtentsTest::tearDown() { +-} +- +-//typedef torrent::extents extent_type_1; + typedef torrent::extents extent_type_1; + +-// typedef torrent::extents extent_type_3; +-/* + template + bool + verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) { + while (*idx != *(idx + 1)) { +- if (!extent.is_equal_range(*idx, *(idx + 1) - 1, *val)) { +- // std::cout << *idx << ' ' << *(idx + 1) << ' ' << *val << std::endl; +- // std::cout << extent.at(*idx) << std::endl; +- // std::cout << extent.at(*(idx + 1)) << std::endl; +- return false; ++ for (auto i = *idx; i != *(idx + 1); i++) { ++ lt_log_print(torrent::LOG_MOCK_CALLS, "extent: at %u", i); ++ ++ if (extent.at(i) != *val) ++ return false; + } + + idx++; +@@ -40,34 +31,32 @@ verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) { + } + + static const uint32_t idx_empty[] = {0, 256, 256}; +-static const int val_empty[] = {0, 1}; ++static const int val_empty[] = {0}; + + static const uint32_t idx_basic_1[] = {0, 1, 255, 256, 256}; + static const int val_basic_1[] = {1, 0, 1}; + +-// static const uint32_t idx_basic_2[] = {0, 1, 16, 255, 256, 256}; +-// static const int val_basic_2[] = {1, 0, 2, 1}; +-*/ + void +-ExtentsTest::test_basic() { ++test_extents::test_basic() { + extent_type_1 extent_1; +-/* +- // Test empty. +- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty)); +- +- CPPUNIT_ASSERT(extent_1.at(0) == int()); +- CPPUNIT_ASSERT(extent_1.at(255) == int()); ++ extent_1.insert(0, 255, int()); + +- extent_1.insert(0, 0, 1); +- extent_1.insert(255, 0, 1); ++ { TEST_EXTENT_BEGIN("empty"); ++ CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty)); + +- CPPUNIT_ASSERT(extent_1.at(0) == 1); +- CPPUNIT_ASSERT(extent_1.at(255) == 1); ++ CPPUNIT_ASSERT(extent_1.at(0) == int()); ++ CPPUNIT_ASSERT(extent_1.at(255) == int()); ++ }; ++ { TEST_EXTENT_BEGIN("borders"); + +- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_1, val_basic_1)); ++ extent_1.insert(0, 0, 1); ++ extent_1.insert(255, 255, 1); ++ // This step shouldn't be needed. ++ extent_1.insert(1, 254, int()); + +- // extent_1.insert(38, 3, 2); ++ CPPUNIT_ASSERT(extent_1.at(0) == 1); ++ CPPUNIT_ASSERT(extent_1.at(255) == 1); + +- // CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_2, val_basic_2)); +-*/ ++ CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_1, val_basic_1)); ++ }; + } +diff --git a/test/torrent/utils/test_extents.h b/test/torrent/utils/test_extents.h +index fd790cf8..e187f6a7 100644 +--- a/test/torrent/utils/test_extents.h ++++ b/test/torrent/utils/test_extents.h +@@ -1,13 +1,10 @@ +-#include ++#include "helpers/test_fixture.h" + +-class ExtentsTest : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(ExtentsTest); ++class test_extents : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_extents); + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST_SUITE_END(); + + public: +- void setUp(); +- void tearDown(); +- + void test_basic(); + }; +diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/test_log.cc +similarity index 92% +rename from test/torrent/utils/log_test.cc +rename to test/torrent/utils/test_log.cc +index 8cc00ef8..fec7e505 100644 +--- a/test/torrent/utils/log_test.cc ++++ b/test/torrent/utils/test_log.cc +@@ -1,5 +1,7 @@ + #include "config.h" + ++#include "test_log.h" ++ + #include + #include + #include +@@ -9,15 +11,13 @@ + #include + #include + +-#include "log_test.h" ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log, "torrent/utils"); + + namespace torrent { + typedef std::vector > log_output_list; + extern log_output_list log_outputs; + } + +-CPPUNIT_TEST_SUITE_REGISTRATION(utils_log_test); +- + const char* expected_output = NULL; + unsigned int output_mask; + +@@ -35,19 +35,19 @@ test_output(const char* output, unsigned int length, unsigned int mask) { + CPPUNIT_ASSERT(output_mask == (mask)); + + void +-utils_log_test::setUp() { ++test_log::setUp() { + // Don't initialize since this creates the group->child connections. + // torrent::log_initialize(); + torrent::log_cleanup(); + } + + void +-utils_log_test::tearDown() { ++test_log::tearDown() { + torrent::log_cleanup(); + } + + void +-utils_log_test::test_basic() { ++test_log::test_basic() { + CPPUNIT_ASSERT(!torrent::log_groups.empty()); + CPPUNIT_ASSERT(torrent::log_groups.size() == torrent::LOG_GROUP_MAX_SIZE); + +@@ -61,7 +61,7 @@ open_output(const char* name, int mask = 0) { + } + + void +-utils_log_test::test_output_open() { ++test_log::test_output_open() { + CPPUNIT_ASSERT(torrent::log_groups[0].size_outputs() == 0); + + // Add test for unknown output names. +@@ -92,7 +92,7 @@ utils_log_test::test_output_open() { + // on unused log items. + + void +-utils_log_test::test_print() { ++test_log::test_print() { + open_output("test_print_1", 0x1); + open_output("test_print_2", 0x2); + torrent::log_add_group_output(0, "test_print_1"); +@@ -113,7 +113,7 @@ enum { + }; + + void +-utils_log_test::test_children() { ++test_log::test_children() { + open_output("test_children_1", 0x1); + open_output("test_children_2", 0x2); + torrent::log_add_group_output(GROUP_PARENT_1, "test_children_1"); +@@ -136,8 +136,8 @@ utils_log_test::test_children() { + } + + void +-utils_log_test::test_file_output() { +- std::string filename = "utils_log_test.XXXXXX"; ++test_log::test_file_output() { ++ std::string filename = "test_log.XXXXXX"; + + mktemp(&*filename.begin()); + +@@ -159,8 +159,8 @@ utils_log_test::test_file_output() { + } + + void +-utils_log_test::test_file_output_append() { +- std::string filename = "utils_log_test.XXXXXX"; ++test_log::test_file_output_append() { ++ std::string filename = "test_log.XXXXXX"; + + mktemp(&*filename.begin()); + +diff --git a/test/torrent/utils/log_test.h b/test/torrent/utils/test_log.h +similarity index 71% +rename from test/torrent/utils/log_test.h +rename to test/torrent/utils/test_log.h +index d4cb3bc6..a06c95ae 100644 +--- a/test/torrent/utils/log_test.h ++++ b/test/torrent/utils/test_log.h +@@ -1,9 +1,7 @@ +-#include ++#include "helpers/test_fixture.h" + +-#include "torrent/utils/log.h" +- +-class utils_log_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(utils_log_test); ++class test_log : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_log); + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_output_open); + +diff --git a/test/torrent/utils/test_log_buffer.cc b/test/torrent/utils/test_log_buffer.cc +index a56a5365..58412750 100644 +--- a/test/torrent/utils/test_log_buffer.cc ++++ b/test/torrent/utils/test_log_buffer.cc +@@ -7,18 +7,10 @@ + + CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log_buffer, "torrent/utils"); + +-void +-test_log_buffer::setUp() { +- torrent::cachedTime = rak::timer::from_seconds(1000); +-} +- +-void +-test_log_buffer::tearDown() { +-} +- + void + test_log_buffer::test_basic() { + torrent::log_buffer log; ++ torrent::cachedTime = rak::timer::from_seconds(1000); + + log.lock(); + CPPUNIT_ASSERT(log.empty()); +@@ -46,6 +38,7 @@ test_log_buffer::test_basic() { + void + test_log_buffer::test_timestamps() { + torrent::log_buffer log; ++ torrent::cachedTime = rak::timer::from_seconds(1000); + + log.lock_and_push_log("foobar", 6, 0); + CPPUNIT_ASSERT(log.back().timestamp == 1000); +diff --git a/test/torrent/utils/test_log_buffer.h b/test/torrent/utils/test_log_buffer.h +index 290df4c1..39c6b879 100644 +--- a/test/torrent/utils/test_log_buffer.h ++++ b/test/torrent/utils/test_log_buffer.h +@@ -2,16 +2,11 @@ + + class test_log_buffer : public test_fixture { + CPPUNIT_TEST_SUITE(test_log_buffer); +- + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_timestamps); +- + CPPUNIT_TEST_SUITE_END(); + + public: +- void setUp(); +- void tearDown(); +- + void test_basic(); + void test_timestamps(); + }; +diff --git a/test/torrent/utils/option_strings_test.cc b/test/torrent/utils/test_option_strings.cc +similarity index 65% +rename from test/torrent/utils/option_strings_test.cc +rename to test/torrent/utils/test_option_strings.cc +index a9bdcc89..68da1d2b 100644 +--- a/test/torrent/utils/option_strings_test.cc ++++ b/test/torrent/utils/test_option_strings.cc +@@ -1,35 +1,22 @@ + #include "config.h" + +-#include +-#include +-#include ++#include "test_option_strings.h" + +-#include +-#include +- +-#include +-#include + #include +-#include +-#include ++#include + #include + +-#include "option_strings_test.h" +- +-CPPUNIT_TEST_SUITE_REGISTRATION(option_strings_test); +- +-void +-option_strings_test::test_basic() { +- +-} ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_option_strings, "torrent/utils"); + + #define TEST_ENTRY(group, name, value) \ +- { std::string result(torrent::option_as_string(torrent::group, value)); \ ++ { lt_log_print(torrent::LOG_MOCK_CALLS, "option_string: %s", name); \ ++ std::string result(torrent::option_as_string(torrent::group, value)); \ + CPPUNIT_ASSERT_MESSAGE("Not found '" + result + "'", result == name); \ +- CPPUNIT_ASSERT(torrent::option_find_string(torrent::group, name) == value); } ++ CPPUNIT_ASSERT(torrent::option_find_string(torrent::group, name) == value); \ ++ } + + void +-option_strings_test::test_entries() { ++test_option_strings::test_entries() { + TEST_ENTRY(OPTION_CONNECTION_TYPE, "leech", torrent::Download::CONNECTION_LEECH); + TEST_ENTRY(OPTION_CONNECTION_TYPE, "seed", torrent::Download::CONNECTION_SEED); + TEST_ENTRY(OPTION_CONNECTION_TYPE, "initial_seed", torrent::Download::CONNECTION_INITIAL_SEED); +diff --git a/test/torrent/utils/test_option_strings.h b/test/torrent/utils/test_option_strings.h +new file mode 100644 +index 00000000..dc86e735 +--- /dev/null ++++ b/test/torrent/utils/test_option_strings.h +@@ -0,0 +1,10 @@ ++#include "helpers/test_fixture.h" ++ ++class test_option_strings : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_option_strings); ++ CPPUNIT_TEST(test_entries); ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void test_entries(); ++}; +diff --git a/test/torrent/utils/test_queue_buckets.cc b/test/torrent/utils/test_queue_buckets.cc +index a32d17e7..49d1bae6 100644 +--- a/test/torrent/utils/test_queue_buckets.cc ++++ b/test/torrent/utils/test_queue_buckets.cc +@@ -5,7 +5,7 @@ + #include "utils/instrumentation.h" + #include "utils/queue_buckets.h" + +-CPPUNIT_TEST_SUITE_REGISTRATION(TestQueueBuckets); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_queue_buckets, "torrent/utils"); + + struct test_constants { + static const int bucket_count = 2; +@@ -87,7 +87,7 @@ struct test_queue_bucket_compare { + // + + void +-TestQueueBuckets::test_basic() { ++test_queue_buckets::test_basic() { + torrent::instrumentation_initialize(); + + buckets_type buckets; +@@ -129,7 +129,7 @@ TestQueueBuckets::test_basic() { + } + + void +-TestQueueBuckets::test_erase() { ++test_queue_buckets::test_erase() { + items_destroyed = 0; + torrent::instrumentation_initialize(); + +@@ -162,7 +162,7 @@ bucket_queue_find_in_any(const buckets_type& buckets, int value) { + } + + void +-TestQueueBuckets::test_find() { ++test_queue_buckets::test_find() { + items_destroyed = 0; + torrent::instrumentation_initialize(); + +@@ -183,7 +183,7 @@ TestQueueBuckets::test_find() { + } + + void +-TestQueueBuckets::test_destroy_range() { ++test_queue_buckets::test_destroy_range() { + items_destroyed = 0; + torrent::instrumentation_initialize(); + +@@ -206,7 +206,7 @@ TestQueueBuckets::test_destroy_range() { + } + + void +-TestQueueBuckets::test_move_range() { ++test_queue_buckets::test_move_range() { + items_destroyed = 0; + torrent::instrumentation_initialize(); + +diff --git a/test/torrent/utils/test_queue_buckets.h b/test/torrent/utils/test_queue_buckets.h +index 94624573..a7f1c30a 100644 +--- a/test/torrent/utils/test_queue_buckets.h ++++ b/test/torrent/utils/test_queue_buckets.h +@@ -1,21 +1,18 @@ +-#include ++#include "helpers/test_fixture.h" + +-#include "protocol/request_list.h" ++class test_queue_buckets : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_queue_buckets); + +-class TestQueueBuckets : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(TestQueueBuckets); + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_erase); + CPPUNIT_TEST(test_find); + + CPPUNIT_TEST(test_destroy_range); + CPPUNIT_TEST(test_move_range); ++ + CPPUNIT_TEST_SUITE_END(); + + public: +- void setUp() {} +- void tearDown() {} +- + void test_basic(); + void test_erase(); + void test_find(); +diff --git a/test/torrent/utils/signal_bitfield_test.cc b/test/torrent/utils/test_signal_bitfield.cc +similarity index 85% +rename from test/torrent/utils/signal_bitfield_test.cc +rename to test/torrent/utils/test_signal_bitfield.cc +index 34b622b3..4ecd18c0 100644 +--- a/test/torrent/utils/signal_bitfield_test.cc ++++ b/test/torrent/utils/test_signal_bitfield.cc +@@ -1,13 +1,15 @@ + #include "config.h" + ++#include "test_signal_bitfield.h" ++ ++#include "helpers/test_thread.h" ++#include "helpers/test_utils.h" ++ + #include + #include + #include + +-#include "signal_bitfield_test.h" +-#include "thread_base_test.h" +- +-CPPUNIT_TEST_SUITE_REGISTRATION(utils_signal_bitfield_test); ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_signal_bitfield, "torrent/utils"); + + static void + mark_index(uint32_t* bitfield, unsigned int index) { +@@ -20,13 +22,10 @@ check_index(uint32_t* bitfield, unsigned int index) { + } + + void +-utils_signal_bitfield_test::setUp() { +-} +- +-void +-utils_signal_bitfield_test::tearDown() { ++test_signal_bitfield::tearDown() { + CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); + torrent::thread_base::release_global_lock(); ++ test_fixture::tearDown(); + } + + static bool +@@ -54,7 +53,7 @@ verify_did_internal_error(std::function func, bool should_throw + did_throw)); + + void +-utils_signal_bitfield_test::test_basic() { ++test_signal_bitfield::test_basic() { + SETUP_SIGNAL_BITFIELD(); + + CPPUNIT_ASSERT(torrent::signal_bitfield::max_size == sizeof(torrent::signal_bitfield::bitfield_type) * 8); +@@ -68,7 +67,7 @@ utils_signal_bitfield_test::test_basic() { + } + + void +-utils_signal_bitfield_test::test_single() { ++test_signal_bitfield::test_single() { + SETUP_SIGNAL_BITFIELD(); + + CPPUNIT_ASSERT(signal_bitfield.add_signal(std::bind(&mark_index, &marked_bitfield, 0)) == 0); +@@ -86,7 +85,7 @@ utils_signal_bitfield_test::test_single() { + } + + void +-utils_signal_bitfield_test::test_multiple() { ++test_signal_bitfield::test_multiple() { + SETUP_SIGNAL_BITFIELD(); + + for (unsigned int i = 0; i < torrent::signal_bitfield::max_size; i++) +@@ -106,10 +105,10 @@ utils_signal_bitfield_test::test_multiple() { + } + + void +-utils_signal_bitfield_test::test_thread() { ++test_signal_bitfield::test_threaded() { + uint32_t marked_bitfield = 0; +- thread_test* thread = new thread_test; +- // thread->set_test_flag(thread_test::test_flag_long_timeout); ++ test_thread* thread = new test_thread; ++ // thread->set_test_flag(test_thread::test_flag_long_timeout); + + for (unsigned int i = 0; i < torrent::signal_bitfield::max_size; i++) + CPPUNIT_ASSERT(thread->signal_bitfield()->add_signal(std::bind(&mark_index, &marked_bitfield, i)) == i); +@@ -131,7 +130,7 @@ utils_signal_bitfield_test::test_thread() { + } + + thread->stop_thread(); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE))); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE))); + + delete thread; + } +diff --git a/test/torrent/utils/test_signal_bitfield.h b/test/torrent/utils/test_signal_bitfield.h +new file mode 100644 +index 00000000..2d24d955 +--- /dev/null ++++ b/test/torrent/utils/test_signal_bitfield.h +@@ -0,0 +1,22 @@ ++#include "helpers/test_fixture.h" ++ ++class test_signal_bitfield : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_signal_bitfield); ++ ++ CPPUNIT_TEST(test_basic); ++ CPPUNIT_TEST(test_single); ++ CPPUNIT_TEST(test_multiple); ++ ++ CPPUNIT_TEST(test_threaded); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void tearDown(); ++ ++ void test_basic(); ++ void test_single(); ++ void test_multiple(); ++ ++ void test_threaded(); ++}; +diff --git a/test/torrent/utils/test_thread_base.cc b/test/torrent/utils/test_thread_base.cc +new file mode 100644 +index 00000000..33519b7c +--- /dev/null ++++ b/test/torrent/utils/test_thread_base.cc +@@ -0,0 +1,169 @@ ++#include "config.h" ++ ++#include "test_thread_base.h" ++ ++#include "helpers/test_thread.h" ++#include "helpers/test_utils.h" ++ ++#include ++#include ++ ++#include "torrent/exceptions.h" ++#include "torrent/poll_select.h" ++#include "torrent/utils/log.h" ++#include "torrent/utils/thread_base.h" ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_thread_base, "torrent/utils"); ++ ++#define TEST_BEGIN(name) \ ++ lt_log_print(torrent::LOG_MOCK_CALLS, "thread_base: %s", name); \ ++ ++void throw_shutdown_exception() { throw torrent::shutdown_exception(); } ++ ++void ++test_thread_base::tearDown() { ++ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); ++ torrent::thread_base::release_global_lock(); ++ test_fixture::tearDown(); ++} ++ ++void ++test_thread_base::test_basic() { ++ test_thread* thread = new test_thread; ++ ++ CPPUNIT_ASSERT(thread->flags() == 0); ++ ++ CPPUNIT_ASSERT(!thread->is_main_polling()); ++ CPPUNIT_ASSERT(!thread->is_active()); ++ CPPUNIT_ASSERT(thread->global_queue_size() == 0); ++ CPPUNIT_ASSERT(thread->poll() == NULL); ++ ++ // Check active... ++} ++ ++void ++test_thread_base::test_lifecycle() { ++ test_thread* thread = new test_thread; ++ ++ CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_UNKNOWN); ++ CPPUNIT_ASSERT(thread->test_state() == test_thread::TEST_NONE); ++ ++ thread->init_thread(); ++ CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_INITIALIZED); ++ CPPUNIT_ASSERT(thread->is_initialized()); ++ CPPUNIT_ASSERT(thread->test_state() == test_thread::TEST_PRE_START); ++ ++ thread->set_pre_stop(); ++ CPPUNIT_ASSERT(!wait_for_true(std::bind(&test_thread::is_test_state, thread, test_thread::TEST_PRE_STOP))); ++ ++ thread->start_thread(); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_ACTIVE))); ++ CPPUNIT_ASSERT(thread->is_active()); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_test_state, thread, test_thread::TEST_PRE_STOP))); ++ ++ thread->stop_thread(); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE))); ++ CPPUNIT_ASSERT(thread->is_inactive()); ++ ++ delete thread; ++} ++ ++void ++test_thread_base::test_global_lock_basic() { ++ test_thread* thread = new test_thread; ++ ++ thread->init_thread(); ++ thread->start_thread(); ++ ++ CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0); ++ ++ // Acquire main thread... ++ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); ++ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); ++ ++ torrent::thread_base::release_global_lock(); ++ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); ++ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); ++ ++ torrent::thread_base::release_global_lock(); ++ torrent::thread_base::acquire_global_lock(); ++ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); ++ ++ thread->set_acquire_global(); ++ CPPUNIT_ASSERT(!wait_for_true(std::bind(&test_thread::is_test_flags, thread, test_thread::test_flag_has_global))); ++ ++ torrent::thread_base::release_global_lock(); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_test_flags, thread, test_thread::test_flag_has_global))); ++ ++ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); ++ torrent::thread_base::release_global_lock(); ++ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); ++ ++ // Test waive (loop). ++ ++ CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0); ++ ++ torrent::thread_base::release_global_lock(); ++ thread->stop_thread(); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE))); ++ ++ delete thread; ++} ++ ++void ++test_thread_base::test_interrupt() { ++ test_thread* thread = new test_thread; ++ thread->set_test_flag(test_thread::test_flag_long_timeout); ++ ++ thread->init_thread(); ++ thread->start_thread(); ++ ++ // Vary the various timeouts. ++ ++ for (int i = 0; i < 100; i++) { ++ thread->interrupt(); ++ usleep(0); ++ ++ thread->set_test_flag(test_thread::test_flag_do_work); ++ thread->interrupt(); ++ ++ // Wait for flag to clear. ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_not_test_flags, thread, test_thread::test_flag_do_work))); ++ } ++ ++ thread->stop_thread(); ++ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE))); ++ ++ delete thread; ++} ++ ++void ++test_thread_base::test_stop() { ++ { TEST_BEGIN("trylock global lock"); ++ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); ++ // torrent::thread_base::acquire_global_lock(); ++ }; ++ ++ for (int i = 0; i < 20; i++) { ++ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); ++ ++ test_thread* thread = new test_thread; ++ thread->set_test_flag(test_thread::test_flag_do_work); ++ ++ { TEST_BEGIN("init and start thread"); ++ thread->init_thread(); ++ thread->start_thread(); ++ }; ++ ++ { TEST_BEGIN("stop and delete thread"); ++ thread->stop_thread_wait(); ++ CPPUNIT_ASSERT(thread->is_inactive()); ++ ++ delete thread; ++ } ++ } ++ ++ { TEST_BEGIN("release global lock"); ++ torrent::thread_base::release_global_lock(); ++ }; ++} +diff --git a/test/torrent/utils/test_thread_base.h b/test/torrent/utils/test_thread_base.h +new file mode 100644 +index 00000000..7b2a3432 +--- /dev/null ++++ b/test/torrent/utils/test_thread_base.h +@@ -0,0 +1,25 @@ ++#include "helpers/test_fixture.h" ++ ++class test_thread_base : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_thread_base); ++ ++ CPPUNIT_TEST(test_basic); ++ CPPUNIT_TEST(test_lifecycle); ++ ++ CPPUNIT_TEST(test_global_lock_basic); ++ CPPUNIT_TEST(test_interrupt); ++ CPPUNIT_TEST(test_stop); ++ ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void tearDown(); ++ ++ void test_basic(); ++ void test_lifecycle(); ++ ++ void test_global_lock_basic(); ++ void test_interrupt(); ++ void test_interrupt_legacy(); ++ void test_stop(); ++}; +diff --git a/test/torrent/utils/test_uri_parser.cc b/test/torrent/utils/test_uri_parser.cc +index 1f4bebe8..66d6cda5 100644 +--- a/test/torrent/utils/test_uri_parser.cc ++++ b/test/torrent/utils/test_uri_parser.cc +@@ -2,31 +2,22 @@ + + #include "test_uri_parser.h" + +-#include +-#include ++#include + #include + +-CPPUNIT_TEST_SUITE_REGISTRATION(UriParserTest); +- +-void +-UriParserTest::setUp() { +-} +- +-void +-UriParserTest::tearDown() { +-} ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_uri_parser, "torrent/utils"); + + void + test_print_uri_state(torrent::utils::uri_state state) { +- std::cerr << "state.uri: " << state.uri << std::endl; +- std::cerr << "state.scheme: " << state.scheme << std::endl; +- std::cerr << "state.resource: " << state.resource << std::endl; +- std::cerr << "state.query: " << state.query << std::endl; +- std::cerr << "state.fragment: " << state.fragment << std::endl; ++ lt_log_print(torrent::LOG_MOCK_CALLS, "state.uri: %s", state.uri.c_str()); ++ lt_log_print(torrent::LOG_MOCK_CALLS, "state.scheme: %s", state.scheme.c_str()); ++ lt_log_print(torrent::LOG_MOCK_CALLS, "state.resource: %s", state.resource.c_str()); ++ lt_log_print(torrent::LOG_MOCK_CALLS, "state.query: %s", state.query.c_str()); ++ lt_log_print(torrent::LOG_MOCK_CALLS, "state.fragment: %s", state.fragment.c_str()); + } + + void +-UriParserTest::test_basic() { ++test_uri_parser::test_basic() { + torrent::utils::uri_state state; + + CPPUNIT_ASSERT(state.state == torrent::utils::uri_state::state_empty); +@@ -37,7 +28,7 @@ UriParserTest::test_basic() { + #define MAGNET_BASIC "magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C" + + void +-UriParserTest::test_basic_magnet() { ++test_uri_parser::test_basic_magnet() { + torrent::utils::uri_state state; + + uri_parse_str(MAGNET_BASIC, state); +@@ -63,7 +54,7 @@ UriParserTest::test_basic_magnet() { + #define QUERY_MAGNET "magnet:?" QUERY_MAGNET_QUERY + + void +-UriParserTest::test_query_magnet() { ++test_uri_parser::test_query_magnet() { + torrent::utils::uri_state state; + torrent::utils::uri_query_state query_state; + +@@ -82,7 +73,7 @@ UriParserTest::test_query_magnet() { + uri_parse_query_str(state.query, query_state); + + for (auto element : query_state.elements) +- std::cerr << "query_element: " << element << std::endl; ++ lt_log_print(torrent::LOG_MOCK_CALLS, "query_element: %s", element.c_str()); + + CPPUNIT_ASSERT(query_state.state == torrent::utils::uri_query_state::state_valid); + +diff --git a/test/torrent/utils/test_uri_parser.h b/test/torrent/utils/test_uri_parser.h +index 4f1c2586..f978c8ad 100644 +--- a/test/torrent/utils/test_uri_parser.h ++++ b/test/torrent/utils/test_uri_parser.h +@@ -1,16 +1,15 @@ +-#include ++#include "helpers/test_fixture.h" ++ ++class test_uri_parser : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_uri_parser); + +-class UriParserTest : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(UriParserTest); + CPPUNIT_TEST(test_basic); + CPPUNIT_TEST(test_basic_magnet); + CPPUNIT_TEST(test_query_magnet); ++ + CPPUNIT_TEST_SUITE_END(); + + public: +- void setUp(); +- void tearDown(); +- + void test_basic(); + void test_basic_magnet(); + void test_query_magnet(); +diff --git a/test/torrent/utils/thread_base_test.cc b/test/torrent/utils/thread_base_test.cc +deleted file mode 100644 +index 8366c9ba..00000000 +--- a/test/torrent/utils/thread_base_test.cc ++++ /dev/null +@@ -1,224 +0,0 @@ +-#include "config.h" +- +-#include +-#include +- +-#include +-#include +-#include +- +-#include "thread_base_test.h" +- +-CPPUNIT_TEST_SUITE_REGISTRATION(utils_thread_base_test); +- +-const int thread_test::test_flag_pre_stop; +-const int thread_test::test_flag_long_timeout; +- +-const int thread_test::test_flag_acquire_global; +-const int thread_test::test_flag_has_global; +- +-const int thread_test::test_flag_do_work; +-const int thread_test::test_flag_pre_poke; +-const int thread_test::test_flag_post_poke; +- +-void throw_shutdown_exception() { throw torrent::shutdown_exception(); } +- +-thread_test::thread_test() : +- m_test_state(TEST_NONE), +- m_test_flags(0) { +-} +- +-void +-thread_test::init_thread() { +- m_state = STATE_INITIALIZED; +- m_test_state = TEST_PRE_START; +- m_poll = torrent::PollSelect::create(256); +-} +- +-void +-thread_test::call_events() { +- if ((m_test_flags & test_flag_pre_stop) && m_test_state == TEST_PRE_START && m_state == STATE_ACTIVE) +- __sync_lock_test_and_set(&m_test_state, TEST_PRE_STOP); +- +- if ((m_test_flags & test_flag_acquire_global)) { +- acquire_global_lock(); +- __sync_and_and_fetch(&m_test_flags, ~test_flag_acquire_global); +- __sync_or_and_fetch(&m_test_flags, test_flag_has_global); +- } +- +- if ((m_flags & flag_do_shutdown)) { +- if ((m_flags & flag_did_shutdown)) +- throw torrent::internal_error("Already trigged shutdown."); +- +- __sync_or_and_fetch(&m_flags, flag_did_shutdown); +- throw torrent::shutdown_exception(); +- } +- +- if ((m_test_flags & test_flag_pre_poke)) { +- } +- +- if ((m_test_flags & test_flag_do_work)) { +- usleep(10 * 1000); // TODO: Don't just sleep, as that give up core. +- __sync_and_and_fetch(&m_test_flags, ~test_flag_do_work); +- } +- +- if ((m_test_flags & test_flag_post_poke)) { +- } +-} +- +-bool +-wait_for_true(std::function test_function) { +- int i = 100; +- +- do { +- if (test_function()) +- return true; +- +- usleep(10 * 1000); +- } while (--i); +- +- return false; +-} +- +-void +-utils_thread_base_test::setUp() { +-} +- +-void +-utils_thread_base_test::tearDown() { +- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); +- torrent::thread_base::release_global_lock(); +-} +- +-void +-utils_thread_base_test::test_basic() { +- thread_test* thread = new thread_test; +- +- CPPUNIT_ASSERT(thread->flags() == 0); +- +- CPPUNIT_ASSERT(!thread->is_main_polling()); +- CPPUNIT_ASSERT(!thread->is_active()); +- CPPUNIT_ASSERT(thread->global_queue_size() == 0); +- CPPUNIT_ASSERT(thread->poll() == NULL); +- +- // Check active... +-} +- +-void +-utils_thread_base_test::test_lifecycle() { +- thread_test* thread = new thread_test; +- +- CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_UNKNOWN); +- CPPUNIT_ASSERT(thread->test_state() == thread_test::TEST_NONE); +- +- thread->init_thread(); +- CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_INITIALIZED); +- CPPUNIT_ASSERT(thread->is_initialized()); +- CPPUNIT_ASSERT(thread->test_state() == thread_test::TEST_PRE_START); +- +- thread->set_pre_stop(); +- CPPUNIT_ASSERT(!wait_for_true(std::bind(&thread_test::is_test_state, thread, thread_test::TEST_PRE_STOP))); +- +- thread->start_thread(); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_ACTIVE))); +- CPPUNIT_ASSERT(thread->is_active()); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_test_state, thread, thread_test::TEST_PRE_STOP))); +- +- thread->stop_thread(); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE))); +- CPPUNIT_ASSERT(thread->is_inactive()); +- +- delete thread; +-} +- +-void +-utils_thread_base_test::test_global_lock_basic() { +- thread_test* thread = new thread_test; +- +- thread->init_thread(); +- thread->start_thread(); +- +- CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0); +- +- // Acquire main thread... +- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); +- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); +- +- torrent::thread_base::release_global_lock(); +- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); +- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); +- +- torrent::thread_base::release_global_lock(); +- torrent::thread_base::acquire_global_lock(); +- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); +- +- thread->set_acquire_global(); +- CPPUNIT_ASSERT(!wait_for_true(std::bind(&thread_test::is_test_flags, thread, thread_test::test_flag_has_global))); +- +- torrent::thread_base::release_global_lock(); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_test_flags, thread, thread_test::test_flag_has_global))); +- +- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); +- torrent::thread_base::release_global_lock(); +- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); +- +- // Test waive (loop). +- +- CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0); +- +- torrent::thread_base::release_global_lock(); +- thread->stop_thread(); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE))); +- +- delete thread; +-} +- +-void +-utils_thread_base_test::test_interrupt() { +- thread_test* thread = new thread_test; +- thread->set_test_flag(thread_test::test_flag_long_timeout); +- +- thread->init_thread(); +- thread->start_thread(); +- +- // Vary the various timeouts. +- +- for (int i = 0; i < 100; i++) { +- thread->interrupt(); +- usleep(0); +- +- thread->set_test_flag(thread_test::test_flag_do_work); +- thread->interrupt(); +- +- // Wait for flag to clear. +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_not_test_flags, thread, thread_test::test_flag_do_work))); +- } +- +- thread->stop_thread(); +- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE))); +- +- delete thread; +-} +- +-void +-utils_thread_base_test::test_stop() { +- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); +- // torrent::thread_base::acquire_global_lock(); +- +- for (int i = 0; i < 20; i++) { +- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock()); +- +- thread_test* thread = new thread_test; +- thread->set_test_flag(thread_test::test_flag_do_work); +- +- thread->init_thread(); +- thread->start_thread(); +- +- thread->stop_thread_wait(); +- CPPUNIT_ASSERT(thread->is_inactive()); +- +- delete thread; +- } +- +- torrent::thread_base::release_global_lock(); +-} +diff --git a/test/torrent/utils/thread_base_test.h b/test/torrent/utils/thread_base_test.h +deleted file mode 100644 +index 22eb99dc..00000000 +--- a/test/torrent/utils/thread_base_test.h ++++ /dev/null +@@ -1,86 +0,0 @@ +-#include +- +-#include "torrent/utils/thread_base.h" +- +-class utils_thread_base_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(utils_thread_base_test); +- CPPUNIT_TEST(test_basic); +- CPPUNIT_TEST(test_lifecycle); +- +- CPPUNIT_TEST(test_global_lock_basic); +- CPPUNIT_TEST(test_interrupt); +- CPPUNIT_TEST(test_stop); +- CPPUNIT_TEST_SUITE_END(); +- +-public: +- void setUp(); +- void tearDown(); +- +- void test_basic(); +- void test_lifecycle(); +- +- void test_global_lock_basic(); +- void test_interrupt(); +- void test_interrupt_legacy(); +- void test_stop(); +-}; +- +-struct thread_management_type { +- thread_management_type() { CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); } +- ~thread_management_type() { torrent::thread_base::release_global_lock(); } +-}; +- +-#define SETUP_THREAD() \ +- thread_management_type thread_management; \ +- torrent::thread_disk* thread_disk = new torrent::thread_disk(); \ +- thread_disk->init_thread(); +- +-#define CLEANUP_THREAD() \ +- CPPUNIT_ASSERT(wait_for_true(std::bind(&torrent::thread_base::is_inactive, thread_disk))); \ +- delete thread_disk; +- +-bool wait_for_true(std::function test_function); +- +-class thread_test : public torrent::thread_base { +-public: +- enum test_state { +- TEST_NONE, +- TEST_PRE_START, +- TEST_PRE_STOP, +- TEST_STOP +- }; +- +- static const int test_flag_pre_stop = 0x1; +- static const int test_flag_long_timeout = 0x2; +- +- static const int test_flag_acquire_global = 0x10; +- static const int test_flag_has_global = 0x20; +- +- static const int test_flag_do_work = 0x100; +- static const int test_flag_pre_poke = 0x200; +- static const int test_flag_post_poke = 0x400; +- +- thread_test(); +- +- int test_state() const { return m_test_state; } +- bool is_state(int state) const { return m_state == state; } +- bool is_test_state(int state) const { return m_test_state == state; } +- bool is_test_flags(int flags) const { return (m_test_flags & flags) == flags; } +- bool is_not_test_flags(int flags) const { return !(m_test_flags & flags); } +- +- const char* name() const { return "test_thread"; } +- +- void init_thread(); +- +- void set_pre_stop() { __sync_or_and_fetch(&m_test_flags, test_flag_pre_stop); } +- void set_acquire_global() { __sync_or_and_fetch(&m_test_flags, test_flag_acquire_global); } +- +- void set_test_flag(int flags) { __sync_or_and_fetch(&m_test_flags, flags); } +- +-private: +- void call_events(); +- int64_t next_timeout_usec() { return (m_test_flags & test_flag_long_timeout) ? (10000 * 1000) : (100 * 1000); } +- +- int m_test_state lt_cacheline_aligned; +- int m_test_flags lt_cacheline_aligned; +-}; +diff --git a/test/tracker/test_tracker_http.cc b/test/tracker/test_tracker_http.cc +new file mode 100644 +index 00000000..399d00d5 +--- /dev/null ++++ b/test/tracker/test_tracker_http.cc +@@ -0,0 +1,11 @@ ++#include "config.h" ++ ++#include "test_tracker_http.h" ++ ++#include "tracker/tracker_http.h" ++ ++CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_tracker_http, "tracker"); ++ ++void ++test_tracker_http::test_basic() { ++} +diff --git a/test/tracker/test_tracker_http.h b/test/tracker/test_tracker_http.h +new file mode 100644 +index 00000000..ab11a8f7 +--- /dev/null ++++ b/test/tracker/test_tracker_http.h +@@ -0,0 +1,12 @@ ++#include "helpers/test_fixture.h" ++ ++#include "torrent/utils/thread_base.h" ++ ++class test_tracker_http : public test_fixture { ++ CPPUNIT_TEST_SUITE(test_tracker_http); ++ CPPUNIT_TEST(test_basic); ++ CPPUNIT_TEST_SUITE_END(); ++ ++public: ++ void test_basic(); ++}; +diff --git a/test/tracker/tracker_http_test.cc b/test/tracker/tracker_http_test.cc +deleted file mode 100644 +index deda4382..00000000 +--- a/test/tracker/tracker_http_test.cc ++++ /dev/null +@@ -1,17 +0,0 @@ +-#include "config.h" +- +-#include "tracker_http_test.h" +- +-#include "tracker/tracker_http.h" +- +-void +-tracker_http_test::setUp() { +-} +- +-void +-tracker_http_test::tearDown() { +-} +- +-void +-tracker_http_test::test_basic() { +-} +diff --git a/test/tracker/tracker_http_test.h b/test/tracker/tracker_http_test.h +deleted file mode 100644 +index 11ff8246..00000000 +--- a/test/tracker/tracker_http_test.h ++++ /dev/null +@@ -1,18 +0,0 @@ +-#include +- +-#include "tracker/tracker_http.h" +- +-class tracker_http_test : public CppUnit::TestFixture { +- CPPUNIT_TEST_SUITE(tracker_http_test); +- CPPUNIT_TEST(test_basic); +- CPPUNIT_TEST(test_scrape); +- CPPUNIT_TEST_SUITE_END(); +- +-public: +- void setUp(); +- void tearDown(); +- +- void test_basic(); +- +- void test_scrape(); +-}; 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 000000000..e860045a7 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch @@ -0,0 +1,22 @@ +From 03e1c95987917bf98534e50fdd718a948540ffb2 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Thu, 25 Feb 2021 00:03:27 +0900 +Subject: [PATCH] Changes automake required files. + +--- + autogen.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/autogen.sh b/autogen.sh +index 79afab8e..6def96dd 100755 +--- a/autogen.sh ++++ b/autogen.sh +@@ -36,7 +36,7 @@ echo automake... + exit 1 + } + +-automake --add-missing --copy --gnu || exit 1 ++automake --add-missing --copy --foreign || exit 1 + + echo autoconf... + (autoconf --version) < /dev/null > /dev/null 2>&1 || { 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 000000000..0ff30731c --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch @@ -0,0 +1,48 @@ +From b4a3888bd891d804a83ae1cee623592725975895 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Sat, 27 Feb 2021 22:11:55 +0900 +Subject: [PATCH] Replaced custom execinfo autoconf test. + +--- + configure.ac | 2 +- + scripts/rak_execinfo.m4 | 11 ----------- + 2 files changed, 1 insertion(+), 12 deletions(-) + delete mode 100644 scripts/rak_execinfo.m4 + +diff --git a/configure.ac b/configure.ac +index 88a46edd..197bbc94 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -34,7 +34,6 @@ RAK_CHECK_CXXFLAGS + RAK_ENABLE_DEBUG + RAK_ENABLE_EXTRA_DEBUG + RAK_ENABLE_WERROR +-RAK_DISABLE_BACKTRACE + + RAK_CHECK_CXX11 + +@@ -58,6 +57,7 @@ TORRENT_WITH_INOTIFY + CC_ATTRIBUTE_VISIBILITY + + AX_CHECK_ZLIB ++AX_EXECINFO + AX_PTHREAD + + PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"]) +diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4 +deleted file mode 100644 +index c1d9b2f8..00000000 +--- a/scripts/rak_execinfo.m4 ++++ /dev/null +@@ -1,11 +0,0 @@ +-AC_DEFUN([RAK_DISABLE_BACKTRACE], [ +- AC_ARG_ENABLE(backtrace, +- AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]), +- [ +- if test "$enableval" = "yes"; then +- AX_EXECINFO +- fi +- ],[ +- AX_EXECINFO +- ]) +-]) 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 000000000..9d3c0fa23 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch @@ -0,0 +1,135 @@ +From e5ed6301e0d07adeaab10e9924a8c9a2e327cdc5 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Thu, 29 Apr 2021 19:33:04 +0900 +Subject: [PATCH] Added option to disable pthread_setname_np. + +--- + configure.ac | 30 +++++++++++++++++++----------- + scripts/checks.m4 | 18 ++++++++++++++++++ + src/torrent/utils/thread_base.cc | 16 ++++++++++++++-- + 3 files changed, 51 insertions(+), 13 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 197bbc94..73caf712 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -24,9 +24,9 @@ AC_PROG_CXX + AC_SYS_LARGEFILE + + AC_C_BIGENDIAN( +- AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian), +- AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian), +- AC_MSG_ERROR([Could not determine endianness]) ++ AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian), ++ AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian), ++ AC_MSG_ERROR([Could not determine endianness]) + ) + + RAK_CHECK_CFLAGS +@@ -54,7 +54,15 @@ TORRENT_WITHOUT_STATVFS + TORRENT_WITHOUT_STATFS + TORRENT_WITH_INOTIFY + +-CC_ATTRIBUTE_VISIBILITY ++AC_ARG_ENABLE(attribute-visibility, ++ AC_HELP_STRING([--disable-attribute-visibility], [disable symbol visibility attribute [[default=enable]]]), ++ [ ++ if test "$enableval" = "yes"; then ++ CC_ATTRIBUTE_VISIBILITY ++ fi ++ ],[ ++ CC_ATTRIBUTE_VISIBILITY ++ ]) + + AX_CHECK_ZLIB + AX_EXECINFO +@@ -71,11 +79,11 @@ TORRENT_ARG_CYRUS_RC4 + + AC_CHECK_FUNCS(posix_memalign) + +-TORRENT_CHECK_MADVISE() +-TORRENT_CHECK_CACHELINE() +-TORRENT_CHECK_POPCOUNT() +-TORRENT_CHECK_PTHREAD_SETNAME_NP() +-TORRENT_MINCORE() ++TORRENT_CHECK_MADVISE ++TORRENT_CHECK_CACHELINE ++TORRENT_CHECK_POPCOUNT ++TORRENT_DISABLE_PTHREAD_SETNAME_NP ++TORRENT_MINCORE + + TORRENT_DISABLE_INSTRUMENTATION + +@@ -88,8 +96,8 @@ AC_SUBST(LIBTORRENT_CFLAGS) + AC_DEFINE(HAVE_CONFIG_H, 1, true if config.h was included) + + CC_ATTRIBUTE_UNUSED( +- AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]), +- AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported]) ++ AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]), ++ AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported]) + ) + + AC_OUTPUT([ +diff --git a/scripts/checks.m4 b/scripts/checks.m4 +index 98ef17f8..915a5011 100644 +--- a/scripts/checks.m4 ++++ b/scripts/checks.m4 +@@ -490,3 +490,21 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [ + ]) + ]) + ]) ++ ++AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [ ++ AC_MSG_CHECKING([for pthread_setname_no]) ++ ++ AC_ARG_ENABLE(pthread-setname-np, ++ AC_HELP_STRING([--disable-pthread-setname-np], [disable pthread_setname_np]), ++ [ ++ if test "$enableval" = "no"; then ++ AC_MSG_RESULT(disabled) ++ else ++ AC_MSG_RESULT(checking) ++ TORRENT_CHECK_PTHREAD_SETNAME_NP ++ fi ++ ], [ ++ TORRENT_CHECK_PTHREAD_SETNAME_NP ++ ] ++ ) ++]) +diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc +index 99d6355d..ec0619f3 100644 +--- a/src/torrent/utils/thread_base.cc ++++ b/src/torrent/utils/thread_base.cc +@@ -41,10 +41,16 @@ thread_base::~thread_base() { + + void + thread_base::start_thread() { +- if (m_poll == NULL) ++ if (this == nullptr) ++ throw internal_error("Called thread_base::start_thread on a nullptr."); ++ ++ if (m_poll == nullptr) + throw internal_error("No poll object for thread defined."); + +- if (!is_initialized() || pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this)) ++ if (!is_initialized()) ++ throw internal_error("Called thread_base::start_thread on an uninitialized object."); ++ ++ if (pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this)) + throw internal_error("Failed to create thread."); + } + +@@ -82,6 +88,12 @@ thread_base::should_handle_sigusr1() { + + void* + thread_base::event_loop(thread_base* thread) { ++ if (thread == nullptr) ++ throw internal_error("thread_base::event_loop called with a null pointer thread"); ++ ++ if (!thread->is_initialized()) ++ throw internal_error("thread_base::event_loop call on an uninitialized object"); ++ + __sync_lock_test_and_set(&thread->m_state, STATE_ACTIVE); + + #if defined(HAS_PTHREAD_SETNAME_NP_DARWIN) 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 000000000..5f48d76bf --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch @@ -0,0 +1,594 @@ +From f978e68f9d907e25207d0a7d247d2b10935e5d76 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Thu, 29 Apr 2021 19:34:35 +0900 +Subject: [PATCH] Improved backtrace error checking. + +--- + src/download/download_main.cc | 36 ------------- + src/download/download_main.h | 36 ------------- + src/download/download_wrapper.cc | 43 ++-------------- + src/torrent/data/download_data.h | 36 ------------- + src/torrent/download/choke_queue.cc | 50 +++++------------- + src/torrent/download/resource_manager.cc | 53 +++++-------------- + src/torrent/exceptions.cc | 65 +++++++----------------- + src/torrent/torrent.cc | 1 + + src/torrent/utils/extents.h | 36 ------------- + src/torrent/utils/signal_bitfield.cc | 36 ------------- + 10 files changed, 48 insertions(+), 344 deletions(-) + +diff --git a/src/download/download_main.cc b/src/download/download_main.cc +index 9a3f9df2..e075038a 100644 +--- a/src/download/download_main.cc ++++ b/src/download/download_main.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +diff --git a/src/download/download_main.h b/src/download/download_main.h +index da3cf182..4783e863 100644 +--- a/src/download/download_main.h ++++ b/src/download/download_main.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_DOWNLOAD_MAIN_H + #define LIBTORRENT_DOWNLOAD_MAIN_H + +diff --git a/src/download/download_wrapper.cc b/src/download/download_wrapper.cc +index 59e81781..304bddce 100644 +--- a/src/download/download_wrapper.cc ++++ b/src/download/download_wrapper.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -62,6 +26,8 @@ + + #include "download_wrapper.h" + ++#define LT_LOG_THIS(log_fmt, ...) \ ++ lt_log_print_info(LOG_TORRENT_INFO, this->info(), "download", log_fmt, __VA_ARGS__); + #define LT_LOG_STORAGE_ERRORS(log_fmt, ...) \ + lt_log_print_info(LOG_PROTOCOL_STORAGE_ERRORS, this->info(), "storage_errors", log_fmt, __VA_ARGS__); + +@@ -325,8 +291,8 @@ DownloadWrapper::receive_tick(uint32_t ticks) { + + void + DownloadWrapper::receive_update_priorities() { +- if (m_main->chunk_selector()->empty()) +- return; ++ LT_LOG_THIS("update priorities: chunks_selected:%" PRIu32 " wanted_chunks:%" PRIu32, ++ m_main->chunk_selector()->size(), data()->wanted_chunks()); + + data()->mutable_high_priority()->clear(); + data()->mutable_normal_priority()->clear(); +@@ -359,7 +325,6 @@ DownloadWrapper::receive_update_priorities() { + } + + bool was_partial = data()->wanted_chunks() != 0; +- + data()->update_wanted_chunks(); + + m_main->chunk_selector()->update_priorities(); +diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h +index fc212047..c701cb2f 100644 +--- a/src/torrent/data/download_data.h ++++ b/src/torrent/data/download_data.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H + #define LIBTORRENT_DATA_DOWNLOAD_DATA_H + +diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc +index 7c00b686..edf47795 100644 +--- a/src/torrent/download/choke_queue.cc ++++ b/src/torrent/download/choke_queue.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -50,6 +14,10 @@ + + #include "choke_queue.h" + ++// TODO: Add a different logging category. ++#define LT_LOG_THIS(log_fmt, ...) \ ++ lt_log_print_subsystem(LOG_TORRENT_INFO, "choke_queue", log_fmt, __VA_ARGS__); ++ + namespace torrent { + + struct choke_manager_less { +@@ -193,6 +161,9 @@ choke_queue::rebuild_containers(container_type* queued, container_type* unchoked + + void + choke_queue::balance() { ++ LT_LOG_THIS("balancing queue: heuristics:%i currently_unchoked:%" PRIu32 " max_unchoked:%" PRIu32, ++ m_heuristics, m_currently_unchoked, m_maxUnchoked) ++ + // Return if no balancing is needed. Don't return if is_unlimited() + // as we might have just changed the value and have interested that + // can be unchoked. +@@ -216,6 +187,9 @@ choke_queue::balance() { + + // If we have more unchoked than max global slots allow for, + // 'can_unchoke' will be negative. ++ // ++ // Throws std::bad_function_call if 'set_slot_can_unchoke' is not ++ // set. + int can_unchoke = m_slotCanUnchoke(); + int max_unchoked = std::min(m_maxUnchoked, (uint32_t)(1 << 20)); + +@@ -240,8 +214,8 @@ choke_queue::balance() { + if (result != 0) + m_slotUnchoke(result); + +- lt_log_print(LOG_PEER_DEBUG, "Called balance; adjust:%i can_unchoke:%i queued:%u unchoked:%u result:%i.", +- adjust, can_unchoke, (unsigned)queued.size(), (unsigned)unchoked.size(), result); ++ LT_LOG_THIS("balanced queue: adjust:%i can_unchoke:%i queued:%" PRIu32 " unchoked:%" PRIu32 " result:%i", ++ adjust, can_unchoke, queued.size(), unchoked.size(), result); + } + + void +diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc +index 51434c91..8ca7b02e 100644 +--- a/src/torrent/download/resource_manager.cc ++++ b/src/torrent/download/resource_manager.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -51,6 +15,11 @@ + #include "choke_queue.h" + #include "resource_manager.h" + ++#define LT_LOG_THIS(log_fmt, ...) \ ++ lt_log_print_subsystem(LOG_TORRENT_INFO, "resource_manager", log_fmt, __VA_ARGS__); ++#define LT_LOG_ITR(log_fmt, ...) \ ++ lt_log_print_info(LOG_TORRENT_INFO, itr->download()->info(), "resource_manager", log_fmt, __VA_ARGS__); ++ + namespace torrent { + + const Rate* resource_manager_entry::up_rate() const { return m_download->info()->up_rate(); } +@@ -226,6 +195,8 @@ ResourceManager::group_index_of(const std::string& name) { + + void + ResourceManager::set_priority(iterator itr, uint16_t pri) { ++ LT_LOG_ITR("set priority: %" PRIu16, 0) ++ + itr->set_priority(pri); + } + +@@ -283,7 +254,7 @@ ResourceManager::set_max_download_unchoked(unsigned int m) { + // possibly multiple calls of this function. + void + ResourceManager::receive_upload_unchoke(int num) { +- lt_log_print(LOG_PEER_INFO, "Upload unchoked slots adjust; currently:%u adjust:%i", m_currentlyUploadUnchoked, num); ++ LT_LOG_THIS("adjusting upload unchoked slots; current:%u adjusted:%i", m_currentlyUploadUnchoked, num); + + if ((int)m_currentlyUploadUnchoked + num < 0) + throw internal_error("ResourceManager::receive_upload_unchoke(...) received an invalid value."); +@@ -293,7 +264,7 @@ ResourceManager::receive_upload_unchoke(int num) { + + void + ResourceManager::receive_download_unchoke(int num) { +- lt_log_print(LOG_PEER_INFO, "Download unchoked slots adjust; currently:%u adjust:%i", m_currentlyDownloadUnchoked, num); ++ LT_LOG_THIS("adjusting download unchoked slots; current:%u adjusted:%i", m_currentlyDownloadUnchoked, num); + + if ((int)m_currentlyDownloadUnchoked + num < 0) + throw internal_error("ResourceManager::receive_download_unchoke(...) received an invalid value."); +@@ -387,12 +358,14 @@ ResourceManager::balance_unchoked(unsigned int weight, unsigned int max_unchoked + std::sort(group_first, group_last, std::bind(std::less(), + std::bind(&choke_group::up_requested, std::placeholders::_1), + std::bind(&choke_group::up_requested, std::placeholders::_2))); +- lt_log_print(LOG_PEER_DEBUG, "Upload unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked); ++ ++ LT_LOG_THIS("balancing upload unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked); + } else { + std::sort(group_first, group_last, std::bind(std::less(), + std::bind(&choke_group::down_requested, std::placeholders::_1), + std::bind(&choke_group::down_requested, std::placeholders::_2))); +- lt_log_print(LOG_PEER_DEBUG, "Download unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked); ++ ++ LT_LOG_THIS("balancing download unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked); + } + + while (group_first != group_last) { +diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc +index f834f9fa..7375ed8e 100644 +--- a/src/torrent/exceptions.cc ++++ b/src/torrent/exceptions.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -73,23 +37,30 @@ void + internal_error::initialize(const std::string& msg) { + m_msg = msg; + +- std::stringstream output; +- + #ifdef HAVE_BACKTRACE +- void* stackPtrs[20]; ++ void* stack_ptrs[20]; ++ int stack_size = ::backtrace(stack_ptrs, 20); ++ char** stack_symbol_names = ::backtrace_symbols(stack_ptrs, stack_size); + +- // Print the stack and exit. +- int stackSize = ::backtrace(stackPtrs, 20); +- char** stackStrings = backtrace_symbols(stackPtrs, stackSize); ++ if (stack_symbol_names == nullptr) { ++ m_backtrace = "backtrace_symbols failed"; ++ return; ++ } + +- for (int i = 0; i < stackSize; ++i) +- output << stackStrings[i] << std::endl; ++ std::stringstream output; + +-#else +- output << "Stack dump not enabled." << std::endl; +-#endif ++ for (int i = 0; i < stack_size; ++i) { ++ if (stack_symbol_names[i] != nullptr && stack_symbol_names[i] > (void*)0x1000) ++ output << stack_symbol_names[i] << std::endl; ++ else ++ output << "stack_symbol: nullptr" << std::endl; ++ } + + m_backtrace = output.str(); ++ ++#else ++ m_backtrace = "stack dump not enabled"; ++#endif + } + + } +diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc +index fb70d247..67de4387 100644 +--- a/src/torrent/torrent.cc ++++ b/src/torrent/torrent.cc +@@ -203,6 +203,7 @@ download_priority(Download d) { + return itr->priority(); + } + ++// TODO: Remove this. + void + download_set_priority(Download d, uint32_t pri) { + ResourceManager::iterator itr = manager->resource_manager()->find(d.ptr()->main()); +diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h +index c2b887b1..64605d4a 100644 +--- a/src/torrent/utils/extents.h ++++ b/src/torrent/utils/extents.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_UTILS_EXTENTS_H + #define LIBTORRENT_UTILS_EXTENTS_H + +diff --git a/src/torrent/utils/signal_bitfield.cc b/src/torrent/utils/signal_bitfield.cc +index 82f81e7c..dfc3d1fe 100644 +--- a/src/torrent/utils/signal_bitfield.cc ++++ b/src/torrent/utils/signal_bitfield.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #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 000000000..8937e869f --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch @@ -0,0 +1,199 @@ +From cabc557fdf6f12fee7029081de2cf5de88464c21 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Thu, 29 Apr 2021 21:27:50 +0900 +Subject: [PATCH] Fixed issue with multiple connections from NAT not working. + +--- + src/protocol/handshake.cc | 36 ------------------- + src/torrent/peer/peer_list.cc | 68 +++++++++++------------------------ + src/torrent/peer/peer_list.h | 36 ------------------- + 3 files changed, 20 insertions(+), 120 deletions(-) + +diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc +index 1b877c7a..d6f48e59 100644 +--- a/src/protocol/handshake.cc ++++ b/src/protocol/handshake.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc +index 080a7f13..6ce630f7 100644 +--- a/src/torrent/peer/peer_list.cc ++++ b/src/torrent/peer/peer_list.cc +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #include "config.h" + + #include +@@ -262,8 +226,11 @@ PeerList::available_list_size() const { + return m_available_list->size(); + } + ++// TODO: Rename connecting: + PeerInfo* + PeerList::connected(const sockaddr* sa, int flags) { ++ // TODO: Rewrite to use new socket address api after fixing bug. ++ + const rak::socket_address* address = rak::socket_address::cast_from(sa); + socket_address_key sock_key = socket_address_key::from_sockaddr(sa); + +@@ -281,13 +248,7 @@ PeerList::connected(const sockaddr* sa, int flags) { + // We should also remove any PeerInfo objects already for this + // address. + if ((filter_value & PeerInfo::flag_unwanted)) { +- char ipv4_str[INET_ADDRSTRLEN]; +- uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr); +- +- inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN); +- +- lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str); +- ++ LT_LOG_EVENTS("connecting peer rejected, flagged as unwanted: " LT_LOG_SA_FMT, address->address_str().c_str(), address->port()); + return NULL; + } + +@@ -313,12 +274,23 @@ PeerList::connected(const sockaddr* sa, int flags) { + // + // This also ensure we can connect to peers running on the same + // host as the tracker. +- if (flags & connect_keep_handshakes && +- range.first->second->is_handshake() && +- rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port()) +- m_available_list->buffer()->push_back(*address); ++ // if (flags & connect_keep_handshakes && ++ // range.first->second->is_handshake() && ++ // rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port()) ++ // m_available_list->buffer()->push_back(*address); + +- return NULL; ++ LT_LOG_EVENTS("connecting peer rejected, already connected (buggy, fixme): " LT_LOG_SA_FMT, address->address_str().c_str(), address->port()); ++ ++ // TODO: Verify this works properly, possibly add a check/flag ++ // that allows the handshake manager to notify peer list if the ++ // incoming connection was a duplicate peer hash. ++ ++ //return NULL; ++ ++ peerInfo = new PeerInfo(sa); ++ peerInfo->set_flags(filter_value & PeerInfo::mask_ip_table); ++ ++ base_type::insert(range.second, value_type(sock_key, peerInfo)); + } + + if (flags & connect_filter_recent && +diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h +index 4c2f707d..a9d31a54 100644 +--- a/src/torrent/peer/peer_list.h ++++ b/src/torrent/peer/peer_list.h +@@ -1,39 +1,3 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- + #ifndef LIBTORRENT_PEER_LIST_H + #define LIBTORRENT_PEER_LIST_H + 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 000000000..a631b8de9 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch @@ -0,0 +1,32 @@ +From 532d3e54b3f012dc81530ebb80ded8b26434fdd9 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Wed, 16 Jun 2021 23:28:28 +0900 +Subject: [PATCH] Added '--disable-execinfo' option to configure. + +--- + configure.ac | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/configure.ac b/configure.ac +index 73caf712..a4f051e4 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -64,8 +64,17 @@ AC_ARG_ENABLE(attribute-visibility, + CC_ATTRIBUTE_VISIBILITY + ]) + ++AC_ARG_ENABLE(execinfo, ++ AC_HELP_STRING([--disable-execinfo], [disable libexecinfo [[default=enable]]]), ++ [ ++ if test "$enableval" = "yes"; then ++ AX_EXECINFO ++ fi ++ ],[ ++ AX_EXECINFO ++ ]) ++ + AX_CHECK_ZLIB +-AX_EXECINFO + AX_PTHREAD + + PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"]) 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 000000000..196d2f6af --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch @@ -0,0 +1,457 @@ +From 92781533fc4afab67447e8e6d47a649383179c44 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Sun, 20 Jun 2021 18:10:52 +0900 +Subject: [PATCH] Detect ip address. + +--- + src/net/local_addr.cc | 6 +- + src/torrent/Makefile.am | 5 +- + src/torrent/net/fd.cc | 3 + + src/torrent/net/fd.h | 14 ++-- + src/torrent/net/socket_address.cc | 2 +- + src/torrent/net/socket_address.h | 2 +- + src/torrent/net/utils.cc | 104 ++++++++++++++++++++++++ + src/torrent/net/utils.h | 9 ++ + src/tracker/tracker_http.cc | 104 ++++++++---------------- + test/helpers/network.h | 2 + + test/torrent/net/test_fd.cc | 9 ++ + test/torrent/net/test_socket_address.cc | 2 +- + 12 files changed, 181 insertions(+), 81 deletions(-) + create mode 100755 src/torrent/net/utils.cc + create mode 100755 src/torrent/net/utils.h + +diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc +index 24413265..0c7116cb 100644 +--- a/src/net/local_addr.cc ++++ b/src/net/local_addr.cc +@@ -34,6 +34,8 @@ + // Skomakerveien 33 + // 3185 Skoppum, NORWAY + ++// TODO: Remove. ++ + #include "config.h" + + #include +@@ -241,7 +243,7 @@ bool get_local_address(sa_family_t family, rak::socket_address *address) { + int plen = IFA_PAYLOAD(nlmsg); + for (const rtattr *rta = IFA_RTA(ifa); + RTA_OK(rta, plen); +- rta = RTA_NEXT(rta, plen)) { ++ rta = RTA_NEXT(rta, plen)) { + if (rta->rta_type != IFA_LOCAL && + rta->rta_type != IFA_ADDRESS) { + continue; +@@ -303,7 +305,7 @@ get_local_address(sa_family_t family, rak::socket_address *address) { + dummy_dest.set_address_c_str("4.0.0.0"); + break; + case rak::socket_address::af_inet6: +- dummy_dest.set_address_c_str("2001:700::"); ++ dummy_dest.set_address_c_str("2001:1::"); + break; + default: + throw internal_error("Unknown address family"); +diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am +index 30157b95..5de7e8ae 100644 +--- a/src/torrent/Makefile.am ++++ b/src/torrent/Makefile.am +@@ -46,6 +46,8 @@ libtorrent_torrent_la_SOURCES = \ + net/socket_event.cc \ + net/socket_event.h \ + net/types.h \ ++ net/utils.cc \ ++ net/utils.h \ + \ + peer/choke_status.h \ + peer/client_info.cc \ +@@ -167,7 +169,8 @@ libtorrent_torrent_net_include_HEADERS = \ + net/socket_address.h \ + net/socket_address_key.h \ + net/socket_event.h \ +- net/types.h ++ net/types.h \ ++ net/utils.h + + libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer + libtorrent_torrent_peer_include_HEADERS = \ +diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc +index 07c91779..6d228181 100644 +--- a/src/torrent/net/fd.cc ++++ b/src/torrent/net/fd.cc +@@ -64,6 +64,9 @@ fd_open(fd_flags flags) { + if ((flags & fd_flag_stream)) { + domain = SOCK_STREAM; + protocol = IPPROTO_TCP; ++ } else if ((flags & fd_flag_datagram)) { ++ domain = SOCK_DGRAM; ++ protocol = IPPROTO_UDP; + } else { + LT_LOG_FLAG("fd_open missing socket type"); + errno = EINVAL; +diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h +index a7094646..6ab3302d 100644 +--- a/src/torrent/net/fd.h ++++ b/src/torrent/net/fd.h +@@ -9,11 +9,12 @@ namespace torrent { + + enum fd_flags : int { + fd_flag_stream = 0x1, +- fd_flag_nonblock = 0x10, +- fd_flag_reuse_address = 0x20, +- fd_flag_v4only = 0x40, +- fd_flag_v6only = 0x80, +- fd_flag_all = 0xff, ++ fd_flag_datagram = 0x10, ++ fd_flag_nonblock = 0x20, ++ fd_flag_reuse_address = 0x40, ++ fd_flag_v4only = 0x80, ++ fd_flag_v6only = 0x100, ++ fd_flag_all = 0x1ff, + }; + + constexpr bool fd_valid_flags(fd_flags flags); +@@ -53,7 +54,8 @@ operator |=(fd_flags& lhs, fd_flags rhs) { + constexpr bool + fd_valid_flags(fd_flags flags) { + return +- (flags & fd_flag_stream) && ++ ((flags & fd_flag_stream) || (flags & fd_flag_datagram)) && ++ !((flags & fd_flag_stream) && (flags & fd_flag_datagram)) && + !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) && + !(flags & ~(fd_flag_all)); + } +diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc +index c36ba0ae..078bee25 100644 +--- a/src/torrent/net/socket_address.cc ++++ b/src/torrent/net/socket_address.cc +@@ -135,7 +135,7 @@ sa_unique_ptr + sa_make_unspec() { + sa_unique_ptr sa(new sockaddr); + +- std::memset(sa.get(), 0, sizeof(sa)); ++ std::memset(sa.get(), 0, sizeof(sockaddr)); + sa.get()->sa_family = AF_UNSPEC; + + return sa; +diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h +index f64aee68..b9586ca1 100644 +--- a/src/torrent/net/socket_address.h ++++ b/src/torrent/net/socket_address.h +@@ -102,8 +102,8 @@ bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_E + + inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); } + inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); } +-inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } + inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } ++inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } + inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); } + inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); } + inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); } +diff --git a/src/torrent/net/utils.cc b/src/torrent/net/utils.cc +new file mode 100755 +index 00000000..4cb85924 +--- /dev/null ++++ b/src/torrent/net/utils.cc +@@ -0,0 +1,104 @@ ++#import ++ ++#import ++#import ++#import ++#import ++#import ++ ++#define LT_LOG_ERROR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (errno:%i message:'%s')", \ ++ errno, std::strerror(errno)); ++#define LT_LOG_FD(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd); ++#define LT_LOG_FD_ERROR(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \ ++ fd, errno, std::strerror(errno)); ++#define LT_LOG_FD_SIN(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \ ++ fd, sin_pretty_str(sa.get()).c_str()); ++#define LT_LOG_FD_SIN6(log_fmt) \ ++ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \ ++ fd, sin6_pretty_str(sa.get()).c_str()); ++ ++namespace torrent { ++ ++auto detect_local_sin_addr() -> sin_unique_ptr { ++ int fd = fd_open(fd_flag_v4only | fd_flag_datagram); ++ if (fd == -1) { ++ LT_LOG_ERROR("detect_local_sin_addr: open failed"); ++ return sin_unique_ptr(); ++ } ++ ++ // TODO: Check if unique_ptr works. ++ std::shared_ptr _fd(nullptr, [fd](...){ fd_close(fd); }); ++ ++ auto connectAddress = sin_make(); ++ connectAddress.get()->sin_addr.s_addr = htonl(0x04000001); ++ connectAddress.get()->sin_port = 80; ++ ++ if (!fd_connect(fd, reinterpret_cast(connectAddress.get())) && errno != EINPROGRESS) { ++ LT_LOG_FD_ERROR("detect_local_sin_addr: connect failed"); ++ return sin_unique_ptr(); ++ } ++ ++ // TODO: Make sa function. ++ socklen_t socklen = sizeof(sockaddr_in); ++ ++ auto sa = sin_make(); ++ ++ if (::getsockname(fd, reinterpret_cast(sa.get()), &socklen) != 0) { ++ LT_LOG_FD_ERROR("detect_local_sin_addr: getsockname failed"); ++ return sin_unique_ptr(); ++ } ++ if (socklen != sizeof(sockaddr_in)) { ++ LT_LOG_FD("detect_local_sin_addr: getsockname failed, invalid socklen"); ++ return sin_unique_ptr(); ++ } ++ ++ LT_LOG_FD_SIN("detect_local_sin_addr: success"); ++ ++ return sa; ++} ++ ++auto detect_local_sin6_addr() -> sin6_unique_ptr { ++ int fd = fd_open(fd_flag_v6only | fd_flag_datagram); ++ if (fd == -1) { ++ LT_LOG_ERROR("detect_local_sin6_addr: open failed"); ++ return sin6_unique_ptr(); ++ } ++ ++ // TODO: Check if unique_ptr works. ++ std::shared_ptr _fd(nullptr, [fd](...){ fd_close(fd); }); ++ ++ auto connectAddress = sin6_make(); ++ connectAddress.get()->sin6_addr.s6_addr[0] = 0x20; ++ connectAddress.get()->sin6_addr.s6_addr[1] = 0x01; ++ connectAddress.get()->sin6_addr.s6_addr[15] = 0x01; ++ connectAddress.get()->sin6_port = 80; ++ ++ if (!fd_connect(fd, reinterpret_cast(connectAddress.get())) && errno != EINPROGRESS) { ++ LT_LOG_FD_ERROR("detect_local_sin6_addr: connect failed"); ++ return sin6_unique_ptr(); ++ } ++ ++ // TODO: Make sa function. ++ socklen_t socklen = sizeof(sockaddr_in6); ++ ++ auto sa = sin6_make(); ++ ++ if (::getsockname(fd, reinterpret_cast(sa.get()), &socklen) != 0) { ++ LT_LOG_FD_ERROR("detect_local_sin6_addr: getsockname failed"); ++ return sin6_unique_ptr(); ++ } ++ if (socklen != sizeof(sockaddr_in6)) { ++ LT_LOG_FD("detect_local_sin6_addr: getsockname failed, invalid socklen"); ++ return sin6_unique_ptr(); ++ } ++ ++ LT_LOG_FD_SIN6("detect_local_sin6_addr: success"); ++ ++ return sa; ++} ++ ++} +diff --git a/src/torrent/net/utils.h b/src/torrent/net/utils.h +new file mode 100755 +index 00000000..1d550c51 +--- /dev/null ++++ b/src/torrent/net/utils.h +@@ -0,0 +1,9 @@ ++#import ++#import ++ ++namespace torrent { ++ ++auto detect_local_sin_addr() -> sin_unique_ptr; ++auto detect_local_sin6_addr() -> sin6_unique_ptr; ++ ++} +diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc +index 1bf94107..de3a39ab 100644 +--- a/src/tracker/tracker_http.cc ++++ b/src/tracker/tracker_http.cc +@@ -1,63 +1,29 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2011, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- +-#include "config.h" ++#import "config.h" + + #define __STDC_FORMAT_MACROS + +-#include +-#include +-#include +-#include +- +-#include "net/address_list.h" +-#include "net/local_addr.h" +-#include "torrent/connection_manager.h" +-#include "torrent/download_info.h" +-#include "torrent/exceptions.h" +-#include "torrent/http.h" +-#include "torrent/object_stream.h" +-#include "torrent/tracker_list.h" +-#include "torrent/utils/log.h" +-#include "torrent/utils/option_strings.h" +- +-#include "tracker_http.h" +- +-#include "globals.h" +-#include "manager.h" ++#import ++#import ++#import ++#import ++ ++#import "net/address_list.h" ++#import "net/local_addr.h" ++#import "torrent/connection_manager.h" ++#import "torrent/download_info.h" ++#import "torrent/exceptions.h" ++#import "torrent/http.h" ++#import "torrent/net/utils.h" ++#import "torrent/net/socket_address.h" ++#import "torrent/object_stream.h" ++#import "torrent/tracker_list.h" ++#import "torrent/utils/log.h" ++#import "torrent/utils/option_strings.h" ++ ++#import "tracker_http.h" ++ ++#import "globals.h" ++#import "manager.h" + + #define LT_LOG_TRACKER(log_level, log_fmt, ...) \ + lt_log_print_info(LOG_TRACKER_##log_level, m_parent->info(), "tracker", "[%u] " log_fmt, group(), __VA_ARGS__); +@@ -142,19 +108,19 @@ TrackerHttp::send_state(int state) { + + const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address()); + +- if (!localAddress->is_address_any()) +- s << "&ip=" << localAddress->address_str(); +- +- if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) { +- rak::socket_address local_v6; +- if (get_local_address(rak::socket_address::af_inet6, &local_v6)) +- s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str()); +- } ++ if (localAddress->is_address_any()) { ++ auto ipv4_address = detect_local_sin_addr(); ++ auto ipv6_address = detect_local_sin6_addr(); + +- if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) { +- rak::socket_address local_v4; +- if (get_local_address(rak::socket_address::af_inet, &local_v4)) +- s << "&ipv4=" << local_v4.address_str(); ++ if (ipv4_address != nullptr) { ++ s << "&ipv4=" << sin_addr_str(ipv4_address.get()); ++ } ++ if (ipv6_address != nullptr) { ++ s << "&ipv6=" << sin6_addr_str(ipv6_address.get()); ++ } ++ ++ } else { ++ s << "&ip=" << localAddress->address_str(); + } + + if (info->is_compact()) +diff --git a/test/helpers/network.h b/test/helpers/network.h +index 6cf2f870..eb188426 100644 +--- a/test/helpers/network.h ++++ b/test/helpers/network.h +@@ -112,6 +112,7 @@ wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const + + CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(), + sa != nullptr); ++ + return sa; + } + +@@ -121,6 +122,7 @@ wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, con + + CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(), + sa != nullptr); ++ + return torrent::c_sa_unique_ptr(sa.release()); + } + +diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc +index 5e56f0f3..0a00ccd4 100644 +--- a/test/torrent/net/test_fd.cc ++++ b/test/torrent/net/test_fd.cc +@@ -9,13 +9,22 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net"); + void + test_fd::test_valid_flags() { + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram)); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_datagram)); ++ + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only)); + ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_nonblock)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_reuse_address)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only)); ++ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v6only)); ++ + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only)); + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); ++ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); + + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags())); + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all))); +diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc +index 8a1b0c8a..a27b38bc 100644 +--- a/test/torrent/net/test_socket_address.cc ++++ b/test/torrent/net/test_socket_address.cc +@@ -83,7 +83,7 @@ test_socket_address::test_make() { + CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6); + CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0); + CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0); +- CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0})); ++ CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, (in6_addr{0}))); + CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0); + + torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix(""); 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 000000000..923f5c97c --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch @@ -0,0 +1,85 @@ +From e646ed5427b690b75208510d328457af66b208e8 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Mon, 21 Jun 2021 21:12:56 +0900 +Subject: [PATCH] Added ipv6 options. + +--- + src/torrent/connection_manager.cc | 6 +++++- + src/torrent/connection_manager.h | 13 +++++++++++++ + src/tracker/tracker_http.cc | 13 +++++-------- + 3 files changed, 23 insertions(+), 9 deletions(-) + +diff --git a/src/torrent/connection_manager.cc b/src/torrent/connection_manager.cc +index 972dcbfc..ea5efc58 100644 +--- a/src/torrent/connection_manager.cc ++++ b/src/torrent/connection_manager.cc +@@ -89,7 +89,11 @@ ConnectionManager::ConnectionManager() : + + m_listen(new Listen), + m_listen_port(0), +- m_listen_backlog(SOMAXCONN) { ++ m_listen_backlog(SOMAXCONN), ++ ++ m_block_ipv4(false), ++ m_block_ipv6(false), ++ m_prefer_ipv6(false) { + + m_bindAddress = (new rak::socket_address())->c_sockaddr(); + m_localAddress = (new rak::socket_address())->c_sockaddr(); +diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h +index cf43b0bf..09ccdd28 100644 +--- a/src/torrent/connection_manager.h ++++ b/src/torrent/connection_manager.h +@@ -167,6 +167,15 @@ public: + // For internal usage. + Listen* listen() { return m_listen; } + ++ bool is_block_ipv4() const { return m_block_ipv4; } ++ void set_block_ipv4(bool v) { m_block_ipv4 = v; } ++ ++ bool is_block_ipv6() const { return m_block_ipv6; } ++ void set_block_ipv6(bool v) { m_block_ipv6 = v; } ++ ++ bool is_prefer_ipv6() const { return m_prefer_ipv6; } ++ void set_prefer_ipv6(bool v) { m_prefer_ipv6 = v; } ++ + private: + ConnectionManager(const ConnectionManager&); + void operator = (const ConnectionManager&); +@@ -190,6 +199,10 @@ private: + slot_filter_type m_slot_filter; + slot_resolver_type m_slot_resolver; + slot_throttle_type m_slot_address_throttle; ++ ++ bool m_block_ipv4; ++ bool m_block_ipv6; ++ bool m_prefer_ipv6; + }; + + } +diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc +index de3a39ab..fdbbd58a 100644 +--- a/src/tracker/tracker_http.cc ++++ b/src/tracker/tracker_http.cc +@@ -109,16 +109,13 @@ TrackerHttp::send_state(int state) { + const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address()); + + if (localAddress->is_address_any()) { +- auto ipv4_address = detect_local_sin_addr(); +- auto ipv6_address = detect_local_sin6_addr(); ++ if (manager->connection_manager()->is_prefer_ipv6()) { ++ auto ipv6_address = detect_local_sin6_addr(); + +- if (ipv4_address != nullptr) { +- s << "&ipv4=" << sin_addr_str(ipv4_address.get()); ++ if (ipv6_address != nullptr) { ++ s << "&ip=" << sin6_addr_str(ipv6_address.get()); ++ } + } +- if (ipv6_address != nullptr) { +- s << "&ipv6=" << sin6_addr_str(ipv6_address.get()); +- } +- + } else { + s << "&ip=" << localAddress->address_str(); + } 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 000000000..383984179 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch @@ -0,0 +1,444 @@ +From 54caef85baca975e0be30b4f3f6de01db19c8e19 Mon Sep 17 00:00:00 2001 +From: rakshasa +Date: Mon, 21 Jun 2021 21:28:02 +0900 +Subject: [PATCH] Removed obsolete files. + +--- + src/Makefile.am | 2 - + src/net/local_addr.cc | 329 ------------------------------------ + src/net/local_addr.h | 64 ------- + src/tracker/tracker_http.cc | 1 - + 4 files changed, 396 deletions(-) + delete mode 100644 src/net/local_addr.cc + delete mode 100644 src/net/local_addr.h + +diff --git a/src/Makefile.am b/src/Makefile.am +index 95e6a7ae..925e7e15 100644 +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -76,8 +76,6 @@ libtorrent_other_la_SOURCES = \ + net/address_list.cc \ + net/address_list.h \ + net/data_buffer.h \ +- net/local_addr.cc \ +- net/local_addr.h \ + net/listen.cc \ + net/listen.h \ + net/protocol_buffer.h \ +diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc +deleted file mode 100644 +index 0c7116cb..00000000 +--- a/src/net/local_addr.cc ++++ /dev/null +@@ -1,329 +0,0 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2007, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- +-// TODO: Remove. +- +-#include "config.h" +- +-#include +-#include +-#include +-#include +- +-#ifdef __linux__ +-#include +-#include +-#endif +- +-#include "torrent/exceptions.h" +-#include "socket_fd.h" +-#include "local_addr.h" +- +-namespace torrent { +- +-#ifdef __linux__ +- +-namespace { +- +-// IPv4 priority, from highest to lowest: +-// +-// 1. Everything else (global address) +-// 2. Private address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) +-// 3. Empty/INADDR_ANY (0.0.0.0) +-// 4. Link-local address (169.254.0.0/16) +-// 5. Localhost (127.0.0.0/8) +-int +-get_priority_ipv4(const in_addr& addr) { +- if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x7f000000U)) { +- return 5; +- } +- if ((addr.s_addr & htonl(0xffff0000U)) == htonl(0xa9fe0000U)) { +- return 4; +- } +- if (addr.s_addr == htonl(0)) { +- return 3; +- } +- if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x0a000000U) || +- (addr.s_addr & htonl(0xfff00000U)) == htonl(0xac100000U) || +- (addr.s_addr & htonl(0xffff0000U)) == htonl(0xc0a80000U)) { +- return 2; +- } +- return 1; +-} +- +-// IPv6 priority, from highest to lowest: +-// +-// 1. Global address (2000::/16 not in 6to4 or Teredo) +-// 2. 6to4 (2002::/16) +-// 3. Teredo (2001::/32) +-// 4. Empty/INADDR_ANY (::) +-// 5. Everything else (link-local, ULA, etc.) +-int +-get_priority_ipv6(const in6_addr& addr) { +- const uint32_t *addr32 = reinterpret_cast(addr.s6_addr); +- if (addr32[0] == htonl(0) && +- addr32[1] == htonl(0) && +- addr32[2] == htonl(0) && +- addr32[3] == htonl(0)) { +- return 4; +- } +- if (addr32[0] == htonl(0x20010000)) { +- return 3; +- } +- if ((addr32[0] & htonl(0xffff0000)) == htonl(0x20020000)) { +- return 2; +- } +- if ((addr32[0] & htonl(0xe0000000)) == htonl(0x20000000)) { +- return 1; +- } +- return 5; +-} +- +-int +-get_priority(const rak::socket_address& addr) { +- switch (addr.family()) { +- case AF_INET: +- return get_priority_ipv4(addr.c_sockaddr_inet()->sin_addr); +- case AF_INET6: +- return get_priority_ipv6(addr.c_sockaddr_inet6()->sin6_addr); +- default: +- throw torrent::internal_error("Unknown address family given to compare"); +- } +-} +- +-} +- +-// Linux-specific implementation that understands how to filter away +-// understands how to filter away secondary addresses. +-bool get_local_address(sa_family_t family, rak::socket_address *address) { +- rak::socket_address best_addr; +- switch (family) { +- case AF_INET: +- best_addr.sa_inet()->clear(); +- break; +- case AF_INET6: +- best_addr.sa_inet6()->clear(); +- break; +- default: +- throw torrent::internal_error("Unknown address family given to get_local_address"); +- } +- +- // The bottom bit of the priority is used to hold if the address is +- // a secondary address (e.g. with IPv6 privacy extensions) or not; +- // secondary addresses have lower priority (higher number). +- int best_addr_pri = get_priority(best_addr) * 2; +- +- // Get all the addresses via Linux' netlink interface. +- int fd = ::socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); +- if (fd == -1) { +- return false; +- } +- +- struct sockaddr_nl nladdr; +- memset(&nladdr, 0, sizeof(nladdr)); +- nladdr.nl_family = AF_NETLINK; +- if (::bind(fd, (sockaddr *)&nladdr, sizeof(nladdr))) { +- ::close(fd); +- return false; +- } +- +- const int seq_no = 1; +- struct { +- nlmsghdr nh; +- rtgenmsg g; +- } req; +- memset(&req, 0, sizeof(req)); +- +- req.nh.nlmsg_len = sizeof(req); +- req.nh.nlmsg_type = RTM_GETADDR; +- req.nh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; +- req.nh.nlmsg_pid = getpid(); +- req.nh.nlmsg_seq = seq_no; +- req.g.rtgen_family = AF_UNSPEC; +- +- int ret; +- do { +- ret = ::sendto(fd, &req, sizeof(req), 0, (sockaddr *)&nladdr, sizeof(nladdr)); +- } while (ret == -1 && errno == EINTR); +- +- if (ret == -1) { +- ::close(fd); +- return false; +- } +- +- bool done = false; +- do { +- char buf[4096]; +- socklen_t len = sizeof(nladdr); +- do { +- ret = ::recvfrom(fd, buf, sizeof(buf), 0, (sockaddr *)&nladdr, &len); +- } while (ret == -1 && errno == EINTR); +- +- if (ret < 0) { +- ::close(fd); +- return false; +- } +- +- for (const nlmsghdr *nlmsg = (const nlmsghdr *)buf; +- NLMSG_OK(nlmsg, ret); +- nlmsg = NLMSG_NEXT(nlmsg, ret)) { +- if (nlmsg->nlmsg_seq != seq_no) +- continue; +- if (nlmsg->nlmsg_type == NLMSG_DONE) { +- done = true; +- break; +- } +- if (nlmsg->nlmsg_type == NLMSG_ERROR) { +- ::close(fd); +- return false; +- } +- if (nlmsg->nlmsg_type != RTM_NEWADDR) +- continue; +- +- const ifaddrmsg *ifa = (const ifaddrmsg *)NLMSG_DATA(nlmsg); +- +- if (ifa->ifa_family != family) +- continue; +- +-#ifdef IFA_F_OPTIMISTIC +- if ((ifa->ifa_flags & IFA_F_OPTIMISTIC) != 0) +- continue; +-#endif +-#ifdef IFA_F_DADFAILED +- if ((ifa->ifa_flags & IFA_F_DADFAILED) != 0) +- continue; +-#endif +-#ifdef IFA_F_DEPRECATED +- if ((ifa->ifa_flags & IFA_F_DEPRECATED) != 0) +- continue; +-#endif +-#ifdef IFA_F_TENTATIVE +- if ((ifa->ifa_flags & IFA_F_TENTATIVE) != 0) +- continue; +-#endif +- +- // Since there can be point-to-point links on the machine, we need to keep +- // track of the addresses we've seen for this interface; if we see both +- // IFA_LOCAL and IFA_ADDRESS for an interface, keep only the IFA_LOCAL. +- rak::socket_address this_addr; +- bool seen_addr = false; +- int plen = IFA_PAYLOAD(nlmsg); +- for (const rtattr *rta = IFA_RTA(ifa); +- RTA_OK(rta, plen); +- rta = RTA_NEXT(rta, plen)) { +- if (rta->rta_type != IFA_LOCAL && +- rta->rta_type != IFA_ADDRESS) { +- continue; +- } +- if (rta->rta_type == IFA_ADDRESS && seen_addr) { +- continue; +- } +- seen_addr = true; +- switch (ifa->ifa_family) { +- case AF_INET: +- this_addr.sa_inet()->clear(); +- this_addr.sa_inet()->set_address(*(const in_addr *)RTA_DATA(rta)); +- break; +- case AF_INET6: +- this_addr.sa_inet6()->clear(); +- this_addr.sa_inet6()->set_address(*(const in6_addr *)RTA_DATA(rta)); +- break; +- } +- } +- if (!seen_addr) +- continue; +- +- int this_addr_pri = get_priority(this_addr) * 2; +- if ((ifa->ifa_flags & IFA_F_SECONDARY) == IFA_F_SECONDARY) { +- ++this_addr_pri; +- } +- +- if (this_addr_pri < best_addr_pri) { +- best_addr = this_addr; +- best_addr_pri = this_addr_pri; +- } +- } +- } while (!done); +- +- ::close(fd); +- if (!best_addr.is_address_any()) { +- *address = best_addr; +- return true; +- } else { +- return false; +- } +-} +- +-#else +- +-// Generic POSIX variant. +-bool +-get_local_address(sa_family_t family, rak::socket_address *address) { +- SocketFd sock; +- if (!sock.open_datagram()) { +- return false; +- } +- +- rak::socket_address dummy_dest; +- dummy_dest.clear(); +- +- switch (family) { +- case rak::socket_address::af_inet: +- dummy_dest.set_address_c_str("4.0.0.0"); +- break; +- case rak::socket_address::af_inet6: +- dummy_dest.set_address_c_str("2001:1::"); +- break; +- default: +- throw internal_error("Unknown address family"); +- } +- +- dummy_dest.set_port(80); +- +- if (!sock.connect(dummy_dest)) { +- sock.close(); +- return false; +- } +- +- bool ret = sock.getsockname(address); +- sock.close(); +- +- return ret; +-} +- +-#endif +- +-} +diff --git a/src/net/local_addr.h b/src/net/local_addr.h +deleted file mode 100644 +index 43bc8206..00000000 +--- a/src/net/local_addr.h ++++ /dev/null +@@ -1,64 +0,0 @@ +-// libTorrent - BitTorrent library +-// Copyright (C) 2005-2007, Jari Sundell +-// +-// This program is free software; you can redistribute it and/or modify +-// it under the terms of the GNU General Public License as published by +-// the Free Software Foundation; either version 2 of the License, or +-// (at your option) any later version. +-// +-// This program is distributed in the hope that it will be useful, +-// but WITHOUT ANY WARRANTY; without even the implied warranty of +-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-// GNU General Public License for more details. +-// +-// You should have received a copy of the GNU General Public License +-// along with this program; if not, write to the Free Software +-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +-// +-// In addition, as a special exception, the copyright holders give +-// permission to link the code of portions of this program with the +-// OpenSSL library under certain conditions as described in each +-// individual source file, and distribute linked combinations +-// including the two. +-// +-// You must obey the GNU General Public License in all respects for +-// all of the code used other than OpenSSL. If you modify file(s) +-// with this exception, you may extend this exception to your version +-// of the file(s), but you are not obligated to do so. If you do not +-// wish to do so, delete this exception statement from your version. +-// If you delete this exception statement from all source files in the +-// program, then also delete it here. +-// +-// Contact: Jari Sundell +-// +-// Skomakerveien 33 +-// 3185 Skoppum, NORWAY +- +-// A routine to get a local IP address that can be presented to a tracker. +-// (Does not use UPnP etc., so will not understand NAT.) +-// On a machine with multiple network cards, address selection can be a +-// complex process, and in general what's selected is a source/destination +-// address pair. However, this routine will give an approximation that will +-// be good enough for most purposes and users. +- +-#ifndef LIBTORRENT_NET_LOCAL_ADDR_H +-#define LIBTORRENT_NET_LOCAL_ADDR_H +- +-#include +- +-namespace rak { +- class socket_address; +-} +- +-namespace torrent { +- +-// Note: family must currently be rak::af_inet or rak::af_inet6 +-// (rak::af_unspec won't do); anything else will throw an exception. +-// Returns false if no address of the given family could be found, +-// either because there are none, or because something went wrong in +-// the process (e.g., no free file descriptors). +-bool get_local_address(sa_family_t family, rak::socket_address *address); +- +-} +- +-#endif /* LIBTORRENT_NET_LOCAL_ADDR_H */ +diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc +index fdbbd58a..22c409a1 100644 +--- a/src/tracker/tracker_http.cc ++++ b/src/tracker/tracker_http.cc +@@ -8,7 +8,6 @@ + #import + + #import "net/address_list.h" +-#import "net/local_addr.h" + #import "torrent/connection_manager.h" + #import "torrent/download_info.h" + #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 000000000..965f61a4e --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch @@ -0,0 +1,2979 @@ +From 4cfe9b1dc1349ad167969d6cf87f557600f34a2e Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Sat, 7 Aug 2021 17:49:35 +0900 +Subject: [PATCH] Updated and cleaned up automake. (#224) + +--- + INSTALL | 371 +++++++---- + autogen.sh | 51 -- + configure.ac | 32 +- + scripts/ax_check_zlib.m4 | 11 +- + scripts/ax_cxx_compile_stdcxx.m4 | 962 ++++++++++++++++++++++++++++ + scripts/ax_cxx_compile_stdcxx_0x.m4 | 106 --- + scripts/ax_cxx_compile_stdcxx_11.m4 | 147 ----- + scripts/ax_pthread.m4 | 453 +++++++++---- + scripts/checks.m4 | 104 ++- + scripts/common.m4 | 29 +- + scripts/rak_compiler.m4 | 6 +- + scripts/rak_cxx.m4 | 14 - + 12 files changed, 1642 insertions(+), 644 deletions(-) + delete mode 100755 autogen.sh + mode change 100644 => 100755 scripts/ax_check_zlib.m4 + create mode 100755 scripts/ax_cxx_compile_stdcxx.m4 + delete mode 100644 scripts/ax_cxx_compile_stdcxx_0x.m4 + delete mode 100644 scripts/ax_cxx_compile_stdcxx_11.m4 + mode change 100644 => 100755 scripts/ax_pthread.m4 + delete mode 100644 scripts/rak_cxx.m4 + +diff --git a/INSTALL b/INSTALL +index 54caf7c1..8865734f 100644 +--- a/INSTALL ++++ b/INSTALL +@@ -1,81 +1,109 @@ +-Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software ++Installation Instructions ++************************* ++ ++ Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software + Foundation, Inc. + +- This file is free documentation; the Free Software Foundation gives +-unlimited permission to copy, distribute and modify it. ++ Copying and distribution of this file, with or without modification, ++are permitted in any medium without royalty provided the copyright ++notice and this notice are preserved. This file is offered as-is, ++without warranty of any kind. + + Basic Installation + ================== + +- These are generic installation instructions. ++ Briefly, the shell command './configure && make && make install' ++should configure, build, and install this package. The following ++more-detailed instructions are generic; see the 'README' file for ++instructions specific to this package. Some packages provide this ++'INSTALL' file but do not implement all of the features documented ++below. The lack of an optional feature in a given package is not ++necessarily a bug. More recommendations for GNU packages can be found ++in *note Makefile Conventions: (standards)Makefile Conventions. + +- The `configure' shell script attempts to guess correct values for ++ The 'configure' shell script attempts to guess correct values for + various system-dependent variables used during compilation. It uses +-those values to create a `Makefile' in each directory of the package. +-It may also create one or more `.h' files containing system-dependent +-definitions. Finally, it creates a shell script `config.status' that ++those values to create a 'Makefile' in each directory of the package. ++It may also create one or more '.h' files containing system-dependent ++definitions. Finally, it creates a shell script 'config.status' that + you can run in the future to recreate the current configuration, and a +-file `config.log' containing compiler output (useful mainly for +-debugging `configure'). ++file 'config.log' containing compiler output (useful mainly for ++debugging 'configure'). + +- It can also use an optional file (typically called `config.cache' +-and enabled with `--cache-file=config.cache' or simply `-C') that saves +-the results of its tests to speed up reconfiguring. (Caching is +-disabled by default to prevent problems with accidental use of stale +-cache files.) ++ It can also use an optional file (typically called 'config.cache' and ++enabled with '--cache-file=config.cache' or simply '-C') that saves the ++results of its tests to speed up reconfiguring. Caching is disabled by ++default to prevent problems with accidental use of stale cache files. + + If you need to do unusual things to compile the package, please try +-to figure out how `configure' could check whether to do them, and mail +-diffs or instructions to the address given in the `README' so they can ++to figure out how 'configure' could check whether to do them, and mail ++diffs or instructions to the address given in the 'README' so they can + be considered for the next release. If you are using the cache, and at +-some point `config.cache' contains results you don't want to keep, you ++some point 'config.cache' contains results you don't want to keep, you + may remove or edit it. + +- The file `configure.ac' (or `configure.in') is used to create +-`configure' by a program called `autoconf'. You only need +-`configure.ac' if you want to change it or regenerate `configure' using +-a newer version of `autoconf'. ++ The file 'configure.ac' (or 'configure.in') is used to create ++'configure' by a program called 'autoconf'. You need 'configure.ac' if ++you want to change it or regenerate 'configure' using a newer version of ++'autoconf'. ++ ++ The simplest way to compile this package is: + +-The simplest way to compile this package is: ++ 1. 'cd' to the directory containing the package's source code and type ++ './configure' to configure the package for your system. + +- 1. `cd' to the directory containing the package's source code and type +- `./configure' to configure the package for your system. If you're +- using `csh' on an old version of System V, you might need to type +- `sh ./configure' instead to prevent `csh' from trying to execute +- `configure' itself. ++ Running 'configure' might take a while. While running, it prints ++ some messages telling which features it is checking for. + +- Running `configure' takes awhile. While running, it prints some +- messages telling which features it is checking for. ++ 2. Type 'make' to compile the package. + +- 2. Type `make' to compile the package. ++ 3. Optionally, type 'make check' to run any self-tests that come with ++ the package, generally using the just-built uninstalled binaries. + +- 3. Optionally, type `make check' to run any self-tests that come with +- the package. ++ 4. Type 'make install' to install the programs and any data files and ++ documentation. When installing into a prefix owned by root, it is ++ recommended that the package be configured and built as a regular ++ user, and only the 'make install' phase executed with root ++ privileges. + +- 4. Type `make install' to install the programs and any data files and +- documentation. ++ 5. Optionally, type 'make installcheck' to repeat any self-tests, but ++ this time using the binaries in their final installed location. ++ This target does not install anything. Running this target as a ++ regular user, particularly if the prior 'make install' required ++ root privileges, verifies that the installation completed ++ correctly. + +- 5. You can remove the program binaries and object files from the +- source code directory by typing `make clean'. To also remove the +- files that `configure' created (so you can compile the package for +- a different kind of computer), type `make distclean'. There is +- also a `make maintainer-clean' target, but that is intended mainly ++ 6. You can remove the program binaries and object files from the ++ source code directory by typing 'make clean'. To also remove the ++ files that 'configure' created (so you can compile the package for ++ a different kind of computer), type 'make distclean'. There is ++ also a 'make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + ++ 7. Often, you can also type 'make uninstall' to remove the installed ++ files again. In practice, not all packages have tested that ++ uninstallation works correctly, even though it is required by the ++ GNU Coding Standards. ++ ++ 8. Some packages, particularly those that use Automake, provide 'make ++ distcheck', which can by used by developers to test that all other ++ targets like 'make install' and 'make uninstall' work correctly. ++ This target is generally not run by end users. ++ + Compilers and Options + ===================== + + Some systems require unusual options for compilation or linking that +-the `configure' script does not know about. Run `./configure --help' ++the 'configure' script does not know about. Run './configure --help' + for details on some of the pertinent environment variables. + +- You can give `configure' initial values for configuration parameters +-by setting variables in the command line or in the environment. Here +-is an example: ++ You can give 'configure' initial values for configuration parameters ++by setting variables in the command line or in the environment. Here is ++an example: + +- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix ++ ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +@@ -84,146 +112,257 @@ Compiling For Multiple Architectures + + You can compile the package for more than one kind of computer at the + same time, by placing the object files for each architecture in their +-own directory. To do this, you must use a version of `make' that +-supports the `VPATH' variable, such as GNU `make'. `cd' to the ++own directory. To do this, you can use GNU 'make'. 'cd' to the + directory where you want the object files and executables to go and run +-the `configure' script. `configure' automatically checks for the +-source code in the directory that `configure' is in and in `..'. ++the 'configure' script. 'configure' automatically checks for the source ++code in the directory that 'configure' is in and in '..'. This is known ++as a "VPATH" build. ++ ++ With a non-GNU 'make', it is safer to compile the package for one ++architecture at a time in the source code directory. After you have ++installed the package for one architecture, use 'make distclean' before ++reconfiguring for another architecture. ++ ++ On MacOS X 10.5 and later systems, you can create libraries and ++executables that work on multiple system types--known as "fat" or ++"universal" binaries--by specifying multiple '-arch' options to the ++compiler but only a single '-arch' option to the preprocessor. Like ++this: ++ ++ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ ++ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ ++ CPP="gcc -E" CXXCPP="g++ -E" + +- If you have to use a `make' that does not support the `VPATH' +-variable, you have to compile the package for one architecture at a +-time in the source code directory. After you have installed the +-package for one architecture, use `make distclean' before reconfiguring +-for another architecture. ++ This is not guaranteed to produce working output in all cases, you ++may have to build one architecture at a time and combine the results ++using the 'lipo' tool if you have problems. + + Installation Names + ================== + +- By default, `make install' will install the package's files in +-`/usr/local/bin', `/usr/local/man', etc. You can specify an +-installation prefix other than `/usr/local' by giving `configure' the +-option `--prefix=PATH'. ++ By default, 'make install' installs the package's commands under ++'/usr/local/bin', include files under '/usr/local/include', etc. You ++can specify an installation prefix other than '/usr/local' by giving ++'configure' the option '--prefix=PREFIX', where PREFIX must be an ++absolute file name. + + You can specify separate installation prefixes for + architecture-specific files and architecture-independent files. If you +-give `configure' the option `--exec-prefix=PATH', the package will use +-PATH as the prefix for installing programs and libraries. +-Documentation and other data files will still use the regular prefix. ++pass the option '--exec-prefix=PREFIX' to 'configure', the package uses ++PREFIX as the prefix for installing programs and libraries. ++Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +-options like `--bindir=PATH' to specify different values for particular +-kinds of files. Run `configure --help' for a list of the directories +-you can set and what kinds of files go in them. +- +- If the package supports it, you can cause programs to be installed +-with an extra prefix or suffix on their names by giving `configure' the +-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. ++options like '--bindir=DIR' to specify different values for particular ++kinds of files. Run 'configure --help' for a list of the directories ++you can set and what kinds of files go in them. In general, the default ++for these options is expressed in terms of '${prefix}', so that ++specifying just '--prefix' will affect all of the other directory ++specifications that were not explicitly provided. ++ ++ The most portable way to affect installation locations is to pass the ++correct locations to 'configure'; however, many packages provide one or ++both of the following shortcuts of passing variable assignments to the ++'make install' command line to change installation locations without ++having to reconfigure or recompile. ++ ++ The first method involves providing an override variable for each ++affected directory. For example, 'make install ++prefix=/alternate/directory' will choose an alternate location for all ++directory configuration variables that were expressed in terms of ++'${prefix}'. Any directories that were specified during 'configure', ++but not in terms of '${prefix}', must each be overridden at install time ++for the entire installation to be relocated. The approach of makefile ++variable overrides for each directory variable is required by the GNU ++Coding Standards, and ideally causes no recompilation. However, some ++platforms have known limitations with the semantics of shared libraries ++that end up requiring recompilation when using this method, particularly ++noticeable in packages that use GNU Libtool. ++ ++ The second method involves providing the 'DESTDIR' variable. For ++example, 'make install DESTDIR=/alternate/directory' will prepend ++'/alternate/directory' before all installation names. The approach of ++'DESTDIR' overrides is not required by the GNU Coding Standards, and ++does not work on platforms that have drive letters. On the other hand, ++it does better at avoiding recompilation issues, and works well even ++when some directory options were not specified in terms of '${prefix}' ++at 'configure' time. + + Optional Features + ================= + +- Some packages pay attention to `--enable-FEATURE' options to +-`configure', where FEATURE indicates an optional part of the package. +-They may also pay attention to `--with-PACKAGE' options, where PACKAGE +-is something like `gnu-as' or `x' (for the X Window System). The +-`README' should mention any `--enable-' and `--with-' options that the ++ If the package supports it, you can cause programs to be installed ++with an extra prefix or suffix on their names by giving 'configure' the ++option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. ++ ++ Some packages pay attention to '--enable-FEATURE' options to ++'configure', where FEATURE indicates an optional part of the package. ++They may also pay attention to '--with-PACKAGE' options, where PACKAGE ++is something like 'gnu-as' or 'x' (for the X Window System). The ++'README' should mention any '--enable-' and '--with-' options that the + package recognizes. + +- For packages that use the X Window System, `configure' can usually ++ For packages that use the X Window System, 'configure' can usually + find the X include and library files automatically, but if it doesn't, +-you can use the `configure' options `--x-includes=DIR' and +-`--x-libraries=DIR' to specify their locations. ++you can use the 'configure' options '--x-includes=DIR' and ++'--x-libraries=DIR' to specify their locations. ++ ++ Some packages offer the ability to configure how verbose the ++execution of 'make' will be. For these packages, running './configure ++--enable-silent-rules' sets the default to minimal output, which can be ++overridden with 'make V=1'; while running './configure ++--disable-silent-rules' sets the default to verbose, which can be ++overridden with 'make V=0'. ++ ++Particular systems ++================== ++ ++ On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC ++is not installed, it is recommended to use the following options in ++order to use an ANSI C compiler: ++ ++ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" ++ ++and if that doesn't work, install pre-built binaries of GCC for HP-UX. ++ ++ HP-UX 'make' updates targets which have the same time stamps as their ++prerequisites, which makes it generally unusable when shipped generated ++files such as 'configure' are involved. Use GNU 'make' instead. ++ ++ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot ++parse its '' header file. The option '-nodtk' can be used as a ++workaround. If GNU CC is not installed, it is therefore recommended to ++try ++ ++ ./configure CC="cc" ++ ++and if that doesn't work, try ++ ++ ./configure CC="cc -nodtk" ++ ++ On Solaris, don't put '/usr/ucb' early in your 'PATH'. This ++directory contains several dysfunctional programs; working variants of ++these programs are available in '/usr/bin'. So, if you need '/usr/ucb' ++in your 'PATH', put it _after_ '/usr/bin'. ++ ++ On Haiku, software installed for all users goes in '/boot/common', ++not '/usr/local'. It is recommended to use the following options: ++ ++ ./configure --prefix=/boot/common + + Specifying the System Type + ========================== + +- There may be some features `configure' cannot figure out ++ There may be some features 'configure' cannot figure out + automatically, but needs to determine by the type of machine the package + will run on. Usually, assuming the package is built to be run on the +-_same_ architectures, `configure' can figure that out, but if it prints ++_same_ architectures, 'configure' can figure that out, but if it prints + a message saying it cannot guess the machine type, give it the +-`--build=TYPE' option. TYPE can either be a short name for the system +-type, such as `sun4', or a canonical name which has the form: ++'--build=TYPE' option. TYPE can either be a short name for the system ++type, such as 'sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + + where SYSTEM can have one of these forms: + +- OS KERNEL-OS ++ OS ++ KERNEL-OS + +- See the file `config.sub' for the possible values of each field. If +-`config.sub' isn't included in this package, then this package doesn't ++ See the file 'config.sub' for the possible values of each field. If ++'config.sub' isn't included in this package, then this package doesn't + need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +-use the `--target=TYPE' option to select the type of system they will ++use the option '--target=TYPE' to select the type of system they will + produce code for. + + If you want to _use_ a cross compiler, that generates code for a + platform different from the build platform, you should specify the + "host" platform (i.e., that on which the generated programs will +-eventually be run) with `--host=TYPE'. ++eventually be run) with '--host=TYPE'. + + Sharing Defaults + ================ + +- If you want to set default values for `configure' scripts to share, +-you can create a site shell script called `config.site' that gives +-default values for variables like `CC', `cache_file', and `prefix'. +-`configure' looks for `PREFIX/share/config.site' if it exists, then +-`PREFIX/etc/config.site' if it exists. Or, you can set the +-`CONFIG_SITE' environment variable to the location of the site script. +-A warning: not all `configure' scripts look for a site script. ++ If you want to set default values for 'configure' scripts to share, ++you can create a site shell script called 'config.site' that gives ++default values for variables like 'CC', 'cache_file', and 'prefix'. ++'configure' looks for 'PREFIX/share/config.site' if it exists, then ++'PREFIX/etc/config.site' if it exists. Or, you can set the ++'CONFIG_SITE' environment variable to the location of the site script. ++A warning: not all 'configure' scripts look for a site script. + + Defining Variables + ================== + + Variables not defined in a site shell script can be set in the +-environment passed to `configure'. However, some packages may run ++environment passed to 'configure'. However, some packages may run + configure again during the build, and the customized values of these + variables may be lost. In order to avoid this problem, you should set +-them in the `configure' command line, using `VAR=value'. For example: ++them in the 'configure' command line, using 'VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +-will cause the specified gcc to be used as the C compiler (unless it is ++causes the specified 'gcc' to be used as the C compiler (unless it is + overridden in the site shell script). + +-`configure' Invocation ++Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an ++Autoconf limitation. Until the limitation is lifted, you can use this ++workaround: ++ ++ CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash ++ ++'configure' Invocation + ====================== + +- `configure' recognizes the following options to control how it ++ 'configure' recognizes the following options to control how it + operates. + +-`--help' +-`-h' +- Print a summary of the options to `configure', and exit. ++'--help' ++'-h' ++ Print a summary of all of the options to 'configure', and exit. ++ ++'--help=short' ++'--help=recursive' ++ Print a summary of the options unique to this package's ++ 'configure', and exit. The 'short' variant lists options used only ++ in the top level, while the 'recursive' variant lists options also ++ present in any nested packages. + +-`--version' +-`-V' +- Print the version of Autoconf used to generate the `configure' ++'--version' ++'-V' ++ Print the version of Autoconf used to generate the 'configure' + script, and exit. + +-`--cache-file=FILE' ++'--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, +- traditionally `config.cache'. FILE defaults to `/dev/null' to ++ traditionally 'config.cache'. FILE defaults to '/dev/null' to + disable caching. + +-`--config-cache' +-`-C' +- Alias for `--cache-file=config.cache'. ++'--config-cache' ++'-C' ++ Alias for '--cache-file=config.cache'. + +-`--quiet' +-`--silent' +-`-q' ++'--quiet' ++'--silent' ++'-q' + Do not print messages saying which checks are being made. To +- suppress all normal output, redirect it to `/dev/null' (any error ++ suppress all normal output, redirect it to '/dev/null' (any error + messages will still be shown). + +-`--srcdir=DIR' ++'--srcdir=DIR' + Look for the package's source code in directory DIR. Usually +- `configure' can determine that directory automatically. ++ 'configure' can determine that directory automatically. ++ ++'--prefix=DIR' ++ Use DIR as the installation prefix. *note Installation Names:: for ++ more details, including other options available for fine-tuning the ++ installation locations. + +-`configure' also accepts some other, not widely useful, options. Run +-`configure --help' for more details. ++'--no-create' ++'-n' ++ Run the configure checks, but stop before creating any output ++ files. + ++'configure' also accepts some other, not widely useful, options. Run ++'configure --help' for more details. +diff --git a/autogen.sh b/autogen.sh +deleted file mode 100755 +index 6def96dd..00000000 +--- a/autogen.sh ++++ /dev/null +@@ -1,51 +0,0 @@ +-#! /bin/sh +- +-echo aclocal... +-(aclocal --version) < /dev/null > /dev/null 2>&1 || { +- echo aclocal not found +- exit 1 +-} +- +-aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1 +- +-echo autoheader... +-(autoheader --version) < /dev/null > /dev/null 2>&1 || { +- echo autoheader not found +- exit 1 +-} +- +-autoheader || exit 1 +- +-echo -n "libtoolize... " +-if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then +- echo "using glibtoolize" +- glibtoolize --automake --copy --force || exit 1 +- +-elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then +- echo "using libtoolize" +- libtoolize --automake --copy --force || exit 1 +- +-else +- echo "libtoolize nor glibtoolize not found" +- exit 1 +-fi +- +-echo automake... +-(automake --version) < /dev/null > /dev/null 2>&1 || { +- echo automake not found +- exit 1 +-} +- +-automake --add-missing --copy --foreign || exit 1 +- +-echo autoconf... +-(autoconf --version) < /dev/null > /dev/null 2>&1 || { +- echo autoconf not found +- exit 1 +-} +- +-autoconf || exit 1 +- +-echo ready to configure +- +-exit 0 +diff --git a/configure.ac b/configure.ac +index a4f051e4..453e2936 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1,10 +1,14 @@ +-AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com) ++AC_INIT([[libtorrent]],[[0.13.8]],[[sundell.software@gmail.com]]) + +-LT_INIT([disable-static]) ++AC_CONFIG_HEADERS([config.h]) ++AC_CONFIG_MACRO_DIRS([scripts]) ++AM_INIT_AUTOMAKE([serial-tests subdir-objects foreign]) ++ ++LT_INIT([[disable-static]]) + + dnl Find a better way to do this +-AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id) +-AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT) ++AC_DEFINE([[PEER_NAME]], [["-lt0D80-"]], [[Identifier that is part of the default peer id.]]) ++AC_DEFINE([[PEER_VERSION]], [["lt\x0D\x80"]], [[4 byte client and version identifier for DHT.]]) + + LIBTORRENT_CURRENT=21 + LIBTORRENT_REVISION=0 +@@ -17,9 +21,6 @@ AC_SUBST(LIBTORRENT_CURRENT) + AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO) + AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO) + +-AM_INIT_AUTOMAKE([serial-tests subdir-objects]) +-AC_CONFIG_HEADERS(config.h) +- + AC_PROG_CXX + AC_SYS_LARGEFILE + +@@ -29,14 +30,14 @@ AC_C_BIGENDIAN( + AC_MSG_ERROR([Could not determine endianness]) + ) + ++AX_CXX_COMPILE_STDCXX(14, noext, mandatory) ++ + RAK_CHECK_CFLAGS + RAK_CHECK_CXXFLAGS + RAK_ENABLE_DEBUG + RAK_ENABLE_EXTRA_DEBUG + RAK_ENABLE_WERROR + +-RAK_CHECK_CXX11 +- + TORRENT_ENABLE_ALIGNED + TORRENT_ENABLE_INTERRUPT_SOCKET + +@@ -55,7 +56,7 @@ TORRENT_WITHOUT_STATFS + TORRENT_WITH_INOTIFY + + AC_ARG_ENABLE(attribute-visibility, +- AC_HELP_STRING([--disable-attribute-visibility], [disable symbol visibility attribute [[default=enable]]]), ++ AS_HELP_STRING([--disable-attribute-visibility],[disable symbol visibility attribute [[default=enable]]]), + [ + if test "$enableval" = "yes"; then + CC_ATTRIBUTE_VISIBILITY +@@ -65,7 +66,7 @@ AC_ARG_ENABLE(attribute-visibility, + ]) + + AC_ARG_ENABLE(execinfo, +- AC_HELP_STRING([--disable-execinfo], [disable libexecinfo [[default=enable]]]), ++ AS_HELP_STRING([--disable-execinfo],[disable libexecinfo [[default=enable]]]), + [ + if test "$enableval" = "yes"; then + AX_EXECINFO +@@ -109,12 +110,13 @@ CC_ATTRIBUTE_UNUSED( + AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported]) + ) + +-AC_OUTPUT([ ++AC_CONFIG_FILES([ + libtorrent.pc + Makefile + src/Makefile + src/torrent/Makefile +- test/Makefile +- test/torrent/net/Makefile +- test/net/Makefile ++ test/Makefile ++ test/torrent/net/Makefile ++ test/net/Makefile + ]) ++AC_OUTPUT +diff --git a/scripts/ax_check_zlib.m4 b/scripts/ax_check_zlib.m4 +old mode 100644 +new mode 100755 +index ae5705f6..1a168430 +--- a/scripts/ax_check_zlib.m4 ++++ b/scripts/ax_check_zlib.m4 +@@ -1,5 +1,5 @@ + # =========================================================================== +-# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html ++# https://www.gnu.org/software/autoconf-archive/ax_check_zlib.html + # =========================================================================== + # + # SYNOPSIS +@@ -47,7 +47,7 @@ + # Public License for more details. + # + # You should have received a copy of the GNU General Public License along +-# with this program. If not, see . ++# with this program. If not, see . + # + # As a special exception, the respective Autoconf Macro's copyright owner + # gives unlimited permission to copy, distribute and modify the configure +@@ -62,7 +62,7 @@ + # modified version of the Autoconf Macro, you may extend this special + # exception to the GPL to apply to your modified version as well. + +-#serial 14 ++#serial 16 + + AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB]) + AC_DEFUN([AX_CHECK_ZLIB], +@@ -108,11 +108,10 @@ then + LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib" + CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" + fi +- AC_LANG_SAVE +- AC_LANG_C ++ AC_LANG_PUSH([C]) + AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no]) + AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no]) +- AC_LANG_RESTORE ++ AC_LANG_POP([C]) + if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes" + then + # +diff --git a/scripts/ax_cxx_compile_stdcxx.m4 b/scripts/ax_cxx_compile_stdcxx.m4 +new file mode 100755 +index 00000000..9413da62 +--- /dev/null ++++ b/scripts/ax_cxx_compile_stdcxx.m4 +@@ -0,0 +1,962 @@ ++# =========================================================================== ++# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html ++# =========================================================================== ++# ++# SYNOPSIS ++# ++# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) ++# ++# DESCRIPTION ++# ++# Check for baseline language coverage in the compiler for the specified ++# version of the C++ standard. If necessary, add switches to CXX and ++# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) ++# or '14' (for the C++14 standard). ++# ++# The second argument, if specified, indicates whether you insist on an ++# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. ++# -std=c++11). If neither is specified, you get whatever works, with ++# preference for no added switch, and then for an extended mode. ++# ++# The third argument, if specified 'mandatory' or if left unspecified, ++# indicates that baseline support for the specified C++ standard is ++# required and that the macro should error out if no mode with that ++# support is found. If specified 'optional', then configuration proceeds ++# regardless, after defining HAVE_CXX${VERSION} if and only if a ++# supporting mode is found. ++# ++# LICENSE ++# ++# Copyright (c) 2008 Benjamin Kosnik ++# Copyright (c) 2012 Zack Weinberg ++# Copyright (c) 2013 Roy Stogner ++# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov ++# Copyright (c) 2015 Paul Norman ++# Copyright (c) 2015 Moritz Klammler ++# Copyright (c) 2016, 2018 Krzesimir Nowak ++# Copyright (c) 2019 Enji Cooper ++# Copyright (c) 2020 Jason Merrill ++# ++# Copying and distribution of this file, with or without modification, are ++# permitted in any medium without royalty provided the copyright notice ++# and this notice are preserved. This file is offered as-is, without any ++# warranty. ++ ++#serial 12 ++ ++dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro ++dnl (serial version number 13). ++ ++AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl ++ m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], ++ [$1], [14], [ax_cxx_compile_alternatives="14 1y"], ++ [$1], [17], [ax_cxx_compile_alternatives="17 1z"], ++ [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl ++ m4_if([$2], [], [], ++ [$2], [ext], [], ++ [$2], [noext], [], ++ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl ++ m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], ++ [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], ++ [$3], [optional], [ax_cxx_compile_cxx$1_required=false], ++ [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) ++ AC_LANG_PUSH([C++])dnl ++ ac_success=no ++ ++ m4_if([$2], [], [dnl ++ AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, ++ ax_cv_cxx_compile_cxx$1, ++ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], ++ [ax_cv_cxx_compile_cxx$1=yes], ++ [ax_cv_cxx_compile_cxx$1=no])]) ++ if test x$ax_cv_cxx_compile_cxx$1 = xyes; then ++ ac_success=yes ++ fi]) ++ ++ m4_if([$2], [noext], [], [dnl ++ if test x$ac_success = xno; then ++ for alternative in ${ax_cxx_compile_alternatives}; do ++ switch="-std=gnu++${alternative}" ++ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) ++ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, ++ $cachevar, ++ [ac_save_CXX="$CXX" ++ CXX="$CXX $switch" ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], ++ [eval $cachevar=yes], ++ [eval $cachevar=no]) ++ CXX="$ac_save_CXX"]) ++ if eval test x\$$cachevar = xyes; then ++ CXX="$CXX $switch" ++ if test -n "$CXXCPP" ; then ++ CXXCPP="$CXXCPP $switch" ++ fi ++ ac_success=yes ++ break ++ fi ++ done ++ fi]) ++ ++ m4_if([$2], [ext], [], [dnl ++ if test x$ac_success = xno; then ++ dnl HP's aCC needs +std=c++11 according to: ++ dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf ++ dnl Cray's crayCC needs "-h std=c++11" ++ for alternative in ${ax_cxx_compile_alternatives}; do ++ for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do ++ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) ++ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, ++ $cachevar, ++ [ac_save_CXX="$CXX" ++ CXX="$CXX $switch" ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], ++ [eval $cachevar=yes], ++ [eval $cachevar=no]) ++ CXX="$ac_save_CXX"]) ++ if eval test x\$$cachevar = xyes; then ++ CXX="$CXX $switch" ++ if test -n "$CXXCPP" ; then ++ CXXCPP="$CXXCPP $switch" ++ fi ++ ac_success=yes ++ break ++ fi ++ done ++ if test x$ac_success = xyes; then ++ break ++ fi ++ done ++ fi]) ++ AC_LANG_POP([C++]) ++ if test x$ax_cxx_compile_cxx$1_required = xtrue; then ++ if test x$ac_success = xno; then ++ AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) ++ fi ++ fi ++ if test x$ac_success = xno; then ++ HAVE_CXX$1=0 ++ AC_MSG_NOTICE([No compiler with C++$1 support was found]) ++ else ++ HAVE_CXX$1=1 ++ AC_DEFINE(HAVE_CXX$1,1, ++ [define if the compiler supports basic C++$1 syntax]) ++ fi ++ AC_SUBST(HAVE_CXX$1) ++]) ++ ++ ++dnl Test body for checking C++11 support ++ ++m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], ++ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ++) ++ ++ ++dnl Test body for checking C++14 support ++ ++m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], ++ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ++ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ++) ++ ++m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], ++ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 ++ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ++ _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 ++) ++ ++dnl Tests for new features in C++11 ++ ++m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ ++ ++// If the compiler admits that it is not ready for C++11, why torture it? ++// Hopefully, this will speed up the test. ++ ++#ifndef __cplusplus ++ ++#error "This is not a C++ compiler" ++ ++#elif __cplusplus < 201103L ++ ++#error "This is not a C++11 compiler" ++ ++#else ++ ++namespace cxx11 ++{ ++ ++ namespace test_static_assert ++ { ++ ++ template ++ struct check ++ { ++ static_assert(sizeof(int) <= sizeof(T), "not big enough"); ++ }; ++ ++ } ++ ++ namespace test_final_override ++ { ++ ++ struct Base ++ { ++ virtual ~Base() {} ++ virtual void f() {} ++ }; ++ ++ struct Derived : public Base ++ { ++ virtual ~Derived() override {} ++ virtual void f() override {} ++ }; ++ ++ } ++ ++ namespace test_double_right_angle_brackets ++ { ++ ++ template < typename T > ++ struct check {}; ++ ++ typedef check single_type; ++ typedef check> double_type; ++ typedef check>> triple_type; ++ typedef check>>> quadruple_type; ++ ++ } ++ ++ namespace test_decltype ++ { ++ ++ int ++ f() ++ { ++ int a = 1; ++ decltype(a) b = 2; ++ return a + b; ++ } ++ ++ } ++ ++ namespace test_type_deduction ++ { ++ ++ template < typename T1, typename T2 > ++ struct is_same ++ { ++ static const bool value = false; ++ }; ++ ++ template < typename T > ++ struct is_same ++ { ++ static const bool value = true; ++ }; ++ ++ template < typename T1, typename T2 > ++ auto ++ add(T1 a1, T2 a2) -> decltype(a1 + a2) ++ { ++ return a1 + a2; ++ } ++ ++ int ++ test(const int c, volatile int v) ++ { ++ static_assert(is_same::value == true, ""); ++ static_assert(is_same::value == false, ""); ++ static_assert(is_same::value == false, ""); ++ auto ac = c; ++ auto av = v; ++ auto sumi = ac + av + 'x'; ++ auto sumf = ac + av + 1.0; ++ static_assert(is_same::value == true, ""); ++ static_assert(is_same::value == true, ""); ++ static_assert(is_same::value == true, ""); ++ static_assert(is_same::value == false, ""); ++ static_assert(is_same::value == true, ""); ++ return (sumf > 0.0) ? sumi : add(c, v); ++ } ++ ++ } ++ ++ namespace test_noexcept ++ { ++ ++ int f() { return 0; } ++ int g() noexcept { return 0; } ++ ++ static_assert(noexcept(f()) == false, ""); ++ static_assert(noexcept(g()) == true, ""); ++ ++ } ++ ++ namespace test_constexpr ++ { ++ ++ template < typename CharT > ++ unsigned long constexpr ++ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept ++ { ++ return *s ? strlen_c_r(s + 1, acc + 1) : acc; ++ } ++ ++ template < typename CharT > ++ unsigned long constexpr ++ strlen_c(const CharT *const s) noexcept ++ { ++ return strlen_c_r(s, 0UL); ++ } ++ ++ static_assert(strlen_c("") == 0UL, ""); ++ static_assert(strlen_c("1") == 1UL, ""); ++ static_assert(strlen_c("example") == 7UL, ""); ++ static_assert(strlen_c("another\0example") == 7UL, ""); ++ ++ } ++ ++ namespace test_rvalue_references ++ { ++ ++ template < int N > ++ struct answer ++ { ++ static constexpr int value = N; ++ }; ++ ++ answer<1> f(int&) { return answer<1>(); } ++ answer<2> f(const int&) { return answer<2>(); } ++ answer<3> f(int&&) { return answer<3>(); } ++ ++ void ++ test() ++ { ++ int i = 0; ++ const int c = 0; ++ static_assert(decltype(f(i))::value == 1, ""); ++ static_assert(decltype(f(c))::value == 2, ""); ++ static_assert(decltype(f(0))::value == 3, ""); ++ } ++ ++ } ++ ++ namespace test_uniform_initialization ++ { ++ ++ struct test ++ { ++ static const int zero {}; ++ static const int one {1}; ++ }; ++ ++ static_assert(test::zero == 0, ""); ++ static_assert(test::one == 1, ""); ++ ++ } ++ ++ namespace test_lambdas ++ { ++ ++ void ++ test1() ++ { ++ auto lambda1 = [](){}; ++ auto lambda2 = lambda1; ++ lambda1(); ++ lambda2(); ++ } ++ ++ int ++ test2() ++ { ++ auto a = [](int i, int j){ return i + j; }(1, 2); ++ auto b = []() -> int { return '0'; }(); ++ auto c = [=](){ return a + b; }(); ++ auto d = [&](){ return c; }(); ++ auto e = [a, &b](int x) mutable { ++ const auto identity = [](int y){ return y; }; ++ for (auto i = 0; i < a; ++i) ++ a += b--; ++ return x + identity(a + b); ++ }(0); ++ return a + b + c + d + e; ++ } ++ ++ int ++ test3() ++ { ++ const auto nullary = [](){ return 0; }; ++ const auto unary = [](int x){ return x; }; ++ using nullary_t = decltype(nullary); ++ using unary_t = decltype(unary); ++ const auto higher1st = [](nullary_t f){ return f(); }; ++ const auto higher2nd = [unary](nullary_t f1){ ++ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; ++ }; ++ return higher1st(nullary) + higher2nd(nullary)(unary); ++ } ++ ++ } ++ ++ namespace test_variadic_templates ++ { ++ ++ template ++ struct sum; ++ ++ template ++ struct sum ++ { ++ static constexpr auto value = N0 + sum::value; ++ }; ++ ++ template <> ++ struct sum<> ++ { ++ static constexpr auto value = 0; ++ }; ++ ++ static_assert(sum<>::value == 0, ""); ++ static_assert(sum<1>::value == 1, ""); ++ static_assert(sum<23>::value == 23, ""); ++ static_assert(sum<1, 2>::value == 3, ""); ++ static_assert(sum<5, 5, 11>::value == 21, ""); ++ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); ++ ++ } ++ ++ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae ++ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function ++ // because of this. ++ namespace test_template_alias_sfinae ++ { ++ ++ struct foo {}; ++ ++ template ++ using member = typename T::member_type; ++ ++ template ++ void func(...) {} ++ ++ template ++ void func(member*) {} ++ ++ void test(); ++ ++ void test() { func(0); } ++ ++ } ++ ++} // namespace cxx11 ++ ++#endif // __cplusplus >= 201103L ++ ++]]) ++ ++ ++dnl Tests for new features in C++14 ++ ++m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ ++ ++// If the compiler admits that it is not ready for C++14, why torture it? ++// Hopefully, this will speed up the test. ++ ++#ifndef __cplusplus ++ ++#error "This is not a C++ compiler" ++ ++#elif __cplusplus < 201402L ++ ++#error "This is not a C++14 compiler" ++ ++#else ++ ++namespace cxx14 ++{ ++ ++ namespace test_polymorphic_lambdas ++ { ++ ++ int ++ test() ++ { ++ const auto lambda = [](auto&&... args){ ++ const auto istiny = [](auto x){ ++ return (sizeof(x) == 1UL) ? 1 : 0; ++ }; ++ const int aretiny[] = { istiny(args)... }; ++ return aretiny[0]; ++ }; ++ return lambda(1, 1L, 1.0f, '1'); ++ } ++ ++ } ++ ++ namespace test_binary_literals ++ { ++ ++ constexpr auto ivii = 0b0000000000101010; ++ static_assert(ivii == 42, "wrong value"); ++ ++ } ++ ++ namespace test_generalized_constexpr ++ { ++ ++ template < typename CharT > ++ constexpr unsigned long ++ strlen_c(const CharT *const s) noexcept ++ { ++ auto length = 0UL; ++ for (auto p = s; *p; ++p) ++ ++length; ++ return length; ++ } ++ ++ static_assert(strlen_c("") == 0UL, ""); ++ static_assert(strlen_c("x") == 1UL, ""); ++ static_assert(strlen_c("test") == 4UL, ""); ++ static_assert(strlen_c("another\0test") == 7UL, ""); ++ ++ } ++ ++ namespace test_lambda_init_capture ++ { ++ ++ int ++ test() ++ { ++ auto x = 0; ++ const auto lambda1 = [a = x](int b){ return a + b; }; ++ const auto lambda2 = [a = lambda1(x)](){ return a; }; ++ return lambda2(); ++ } ++ ++ } ++ ++ namespace test_digit_separators ++ { ++ ++ constexpr auto ten_million = 100'000'000; ++ static_assert(ten_million == 100000000, ""); ++ ++ } ++ ++ namespace test_return_type_deduction ++ { ++ ++ auto f(int& x) { return x; } ++ decltype(auto) g(int& x) { return x; } ++ ++ template < typename T1, typename T2 > ++ struct is_same ++ { ++ static constexpr auto value = false; ++ }; ++ ++ template < typename T > ++ struct is_same ++ { ++ static constexpr auto value = true; ++ }; ++ ++ int ++ test() ++ { ++ auto x = 0; ++ static_assert(is_same::value, ""); ++ static_assert(is_same::value, ""); ++ return x; ++ } ++ ++ } ++ ++} // namespace cxx14 ++ ++#endif // __cplusplus >= 201402L ++ ++]]) ++ ++ ++dnl Tests for new features in C++17 ++ ++m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ ++ ++// If the compiler admits that it is not ready for C++17, why torture it? ++// Hopefully, this will speed up the test. ++ ++#ifndef __cplusplus ++ ++#error "This is not a C++ compiler" ++ ++#elif __cplusplus < 201703L ++ ++#error "This is not a C++17 compiler" ++ ++#else ++ ++#include ++#include ++#include ++ ++namespace cxx17 ++{ ++ ++ namespace test_constexpr_lambdas ++ { ++ ++ constexpr int foo = [](){return 42;}(); ++ ++ } ++ ++ namespace test::nested_namespace::definitions ++ { ++ ++ } ++ ++ namespace test_fold_expression ++ { ++ ++ template ++ int multiply(Args... args) ++ { ++ return (args * ... * 1); ++ } ++ ++ template ++ bool all(Args... args) ++ { ++ return (args && ...); ++ } ++ ++ } ++ ++ namespace test_extended_static_assert ++ { ++ ++ static_assert (true); ++ ++ } ++ ++ namespace test_auto_brace_init_list ++ { ++ ++ auto foo = {5}; ++ auto bar {5}; ++ ++ static_assert(std::is_same, decltype(foo)>::value); ++ static_assert(std::is_same::value); ++ } ++ ++ namespace test_typename_in_template_template_parameter ++ { ++ ++ template typename X> struct D; ++ ++ } ++ ++ namespace test_fallthrough_nodiscard_maybe_unused_attributes ++ { ++ ++ int f1() ++ { ++ return 42; ++ } ++ ++ [[nodiscard]] int f2() ++ { ++ [[maybe_unused]] auto unused = f1(); ++ ++ switch (f1()) ++ { ++ case 17: ++ f1(); ++ [[fallthrough]]; ++ case 42: ++ f1(); ++ } ++ return f1(); ++ } ++ ++ } ++ ++ namespace test_extended_aggregate_initialization ++ { ++ ++ struct base1 ++ { ++ int b1, b2 = 42; ++ }; ++ ++ struct base2 ++ { ++ base2() { ++ b3 = 42; ++ } ++ int b3; ++ }; ++ ++ struct derived : base1, base2 ++ { ++ int d; ++ }; ++ ++ derived d1 {{1, 2}, {}, 4}; // full initialization ++ derived d2 {{}, {}, 4}; // value-initialized bases ++ ++ } ++ ++ namespace test_general_range_based_for_loop ++ { ++ ++ struct iter ++ { ++ int i; ++ ++ int& operator* () ++ { ++ return i; ++ } ++ ++ const int& operator* () const ++ { ++ return i; ++ } ++ ++ iter& operator++() ++ { ++ ++i; ++ return *this; ++ } ++ }; ++ ++ struct sentinel ++ { ++ int i; ++ }; ++ ++ bool operator== (const iter& i, const sentinel& s) ++ { ++ return i.i == s.i; ++ } ++ ++ bool operator!= (const iter& i, const sentinel& s) ++ { ++ return !(i == s); ++ } ++ ++ struct range ++ { ++ iter begin() const ++ { ++ return {0}; ++ } ++ ++ sentinel end() const ++ { ++ return {5}; ++ } ++ }; ++ ++ void f() ++ { ++ range r {}; ++ ++ for (auto i : r) ++ { ++ [[maybe_unused]] auto v = i; ++ } ++ } ++ ++ } ++ ++ namespace test_lambda_capture_asterisk_this_by_value ++ { ++ ++ struct t ++ { ++ int i; ++ int foo() ++ { ++ return [*this]() ++ { ++ return i; ++ }(); ++ } ++ }; ++ ++ } ++ ++ namespace test_enum_class_construction ++ { ++ ++ enum class byte : unsigned char ++ {}; ++ ++ byte foo {42}; ++ ++ } ++ ++ namespace test_constexpr_if ++ { ++ ++ template ++ int f () ++ { ++ if constexpr(cond) ++ { ++ return 13; ++ } ++ else ++ { ++ return 42; ++ } ++ } ++ ++ } ++ ++ namespace test_selection_statement_with_initializer ++ { ++ ++ int f() ++ { ++ return 13; ++ } ++ ++ int f2() ++ { ++ if (auto i = f(); i > 0) ++ { ++ return 3; ++ } ++ ++ switch (auto i = f(); i + 4) ++ { ++ case 17: ++ return 2; ++ ++ default: ++ return 1; ++ } ++ } ++ ++ } ++ ++ namespace test_template_argument_deduction_for_class_templates ++ { ++ ++ template ++ struct pair ++ { ++ pair (T1 p1, T2 p2) ++ : m1 {p1}, ++ m2 {p2} ++ {} ++ ++ T1 m1; ++ T2 m2; ++ }; ++ ++ void f() ++ { ++ [[maybe_unused]] auto p = pair{13, 42u}; ++ } ++ ++ } ++ ++ namespace test_non_type_auto_template_parameters ++ { ++ ++ template ++ struct B ++ {}; ++ ++ B<5> b1; ++ B<'a'> b2; ++ ++ } ++ ++ namespace test_structured_bindings ++ { ++ ++ int arr[2] = { 1, 2 }; ++ std::pair pr = { 1, 2 }; ++ ++ auto f1() -> int(&)[2] ++ { ++ return arr; ++ } ++ ++ auto f2() -> std::pair& ++ { ++ return pr; ++ } ++ ++ struct S ++ { ++ int x1 : 2; ++ volatile double y1; ++ }; ++ ++ S f3() ++ { ++ return {}; ++ } ++ ++ auto [ x1, y1 ] = f1(); ++ auto& [ xr1, yr1 ] = f1(); ++ auto [ x2, y2 ] = f2(); ++ auto& [ xr2, yr2 ] = f2(); ++ const auto [ x3, y3 ] = f3(); ++ ++ } ++ ++ namespace test_exception_spec_type_system ++ { ++ ++ struct Good {}; ++ struct Bad {}; ++ ++ void g1() noexcept; ++ void g2(); ++ ++ template ++ Bad ++ f(T*, T*); ++ ++ template ++ Good ++ f(T1*, T2*); ++ ++ static_assert (std::is_same_v); ++ ++ } ++ ++ namespace test_inline_variables ++ { ++ ++ template void f(T) ++ {} ++ ++ template inline T g(T) ++ { ++ return T{}; ++ } ++ ++ template<> inline void f<>(int) ++ {} ++ ++ template<> int g<>(int) ++ { ++ return 5; ++ } ++ ++ } ++ ++} // namespace cxx17 ++ ++#endif // __cplusplus < 201703L ++ ++]]) +diff --git a/scripts/ax_cxx_compile_stdcxx_0x.m4 b/scripts/ax_cxx_compile_stdcxx_0x.m4 +deleted file mode 100644 +index 5ff134a6..00000000 +--- a/scripts/ax_cxx_compile_stdcxx_0x.m4 ++++ /dev/null +@@ -1,106 +0,0 @@ +-# ============================================================================ +-# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html +-# ============================================================================ +-# +-# SYNOPSIS +-# +-# AX_CXX_COMPILE_STDCXX_0X +-# +-# DESCRIPTION +-# +-# Check for baseline language coverage in the compiler for the C++0x +-# standard. +-# +-# LICENSE +-# +-# Copyright (c) 2008 Benjamin Kosnik +-# +-# Copying and distribution of this file, with or without modification, are +-# permitted in any medium without royalty provided the copyright notice +-# and this notice are preserved. This file is offered as-is, without any +-# warranty. +- +-#serial 7 (+1) +- +-AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X]) +-AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [ +- AC_CACHE_CHECK(if g++ supports C++0x features without additional flags, +- ax_cv_cxx_compile_cxx0x_native, +- [AC_LANG_SAVE +- AC_LANG_CPLUSPLUS +- AC_TRY_COMPILE([ +- template +- struct check +- { +- static_assert(sizeof(int) <= sizeof(T), "not big enough"); +- }; +- +- typedef check> right_angle_brackets; +- +- int a; +- decltype(a) b; +- +- typedef check check_type; +- check_type c; +- check_type&& cr = static_cast(c);],, +- ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no) +- AC_LANG_RESTORE +- ]) +- +- AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x, +- ax_cv_cxx_compile_cxx0x_cxx, +- [AC_LANG_SAVE +- AC_LANG_CPLUSPLUS +- ac_save_CXXFLAGS="$CXXFLAGS" +- CXXFLAGS="$CXXFLAGS -std=c++0x" +- AC_TRY_COMPILE([ +- template +- struct check +- { +- static_assert(sizeof(int) <= sizeof(T), "not big enough"); +- }; +- +- typedef check> right_angle_brackets; +- +- int a; +- decltype(a) b; +- +- typedef check check_type; +- check_type c; +- check_type&& cr = static_cast(c);],, +- ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no) +- CXXFLAGS="$ac_save_CXXFLAGS" +- AC_LANG_RESTORE +- ]) +- +- AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x, +- ax_cv_cxx_compile_cxx0x_gxx, +- [AC_LANG_SAVE +- AC_LANG_CPLUSPLUS +- ac_save_CXXFLAGS="$CXXFLAGS" +- CXXFLAGS="$CXXFLAGS -std=gnu++0x" +- AC_TRY_COMPILE([ +- template +- struct check +- { +- static_assert(sizeof(int) <= sizeof(T), "not big enough"); +- }; +- +- typedef check> right_angle_brackets; +- +- int a; +- decltype(a) b; +- +- typedef check check_type; +- check_type c; +- check_type&& cr = static_cast(c);],, +- ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no) +- CXXFLAGS="$ac_save_CXXFLAGS" +- AC_LANG_RESTORE +- ]) +- +- if test "$ax_cv_cxx_compile_cxx0x_cxx" = yes; then +- AC_DEFINE(HAVE_STDCXX_0X,, [Define if compiler supports C++0x features.]) +- CXXFLAGS="$CXXFLAGS -std=c++0x" +- fi +-]) +diff --git a/scripts/ax_cxx_compile_stdcxx_11.m4 b/scripts/ax_cxx_compile_stdcxx_11.m4 +deleted file mode 100644 +index 5cf70eb6..00000000 +--- a/scripts/ax_cxx_compile_stdcxx_11.m4 ++++ /dev/null +@@ -1,147 +0,0 @@ +-# ============================================================================ +-# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html +-# ============================================================================ +-# +-# SYNOPSIS +-# +-# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) +-# +-# DESCRIPTION +-# +-# Check for baseline language coverage in the compiler for the C++11 +-# standard; if necessary, add switches to CXXFLAGS to enable support. +-# +-# The first argument, if specified, indicates whether you insist on an +-# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +-# -std=c++11). If neither is specified, you get whatever works, with +-# preference for an extended mode. +-# +-# The second argument, if specified 'mandatory' or if left unspecified, +-# indicates that baseline C++11 support is required and that the macro +-# should error out if no mode with that support is found. If specified +-# 'optional', then configuration proceeds regardless, after defining +-# HAVE_CXX11 if and only if a supporting mode is found. +-# +-# LICENSE +-# +-# Copyright (c) 2008 Benjamin Kosnik +-# Copyright (c) 2012 Zack Weinberg +-# Copyright (c) 2013 Roy Stogner +-# Copyright (c) 2014 Alexey Sokolov +-# Copyright (c) 2014 Jari Sundell +-# +-# Copying and distribution of this file, with or without modification, are +-# permitted in any medium without royalty provided the copyright notice +-# and this notice are preserved. This file is offered as-is, without any +-# warranty. +- +-#serial 5 +- +-m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ +- template +- struct check +- { +- static_assert(sizeof(int) <= sizeof(T), "not big enough"); +- }; +- +- struct Base { +- virtual void f() {} +- }; +- struct Child : public Base { +- virtual void f() override {} +- }; +- +- typedef check> right_angle_brackets; +- +- int a; +- decltype(a) b; +- +- typedef check check_type; +- check_type c; +- check_type&& cr = static_cast(c); +- +- auto d = a; +- auto l = [](){}; +- +- void unused() { +- l(); +- } +-]]) +- +-AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl +- m4_if([$1], [], [], +- [$1], [ext], [], +- [$1], [noext], [], +- [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl +- m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], +- [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], +- [$2], [optional], [ax_cxx_compile_cxx11_required=false], +- [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) +- AC_LANG_PUSH([C++])dnl +- ac_success=no +- AC_CACHE_CHECK(whether $CXX supports C++11 features by default, +- ax_cv_cxx_compile_cxx11, +- [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], +- [ax_cv_cxx_compile_cxx11=yes], +- [ax_cv_cxx_compile_cxx11=no])]) +- if test x$ax_cv_cxx_compile_cxx11 = xyes; then +- ac_success=yes +- fi +- +- m4_if([$1], [noext], [], [dnl +- if test x$ac_success = xno; then +- for switch in -std=gnu++11 -std=gnu++0x; do +- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) +- AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, +- $cachevar, +- [ac_save_CXXFLAGS="$CXXFLAGS" +- CXXFLAGS="$CXXFLAGS $switch" +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], +- [eval $cachevar=yes], +- [eval $cachevar=no]) +- CXXFLAGS="$ac_save_CXXFLAGS"]) +- if eval test x\$$cachevar = xyes; then +- CXXFLAGS="$CXXFLAGS $switch" +- ac_success=yes +- break +- fi +- done +- fi]) +- +- m4_if([$1], [ext], [], [dnl +- if test x$ac_success = xno; then +- for switch in -std=c++11 -std=c++0x; do +- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) +- AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, +- $cachevar, +- [ac_save_CXXFLAGS="$CXXFLAGS" +- CXXFLAGS="$CXXFLAGS $switch" +- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], +- [eval $cachevar=yes], +- [eval $cachevar=no]) +- CXXFLAGS="$ac_save_CXXFLAGS"]) +- if eval test x\$$cachevar = xyes; then +- CXXFLAGS="$CXXFLAGS $switch" +- ac_success=yes +- break +- fi +- done +- fi]) +- AC_LANG_POP([C++]) +- if test x$ax_cxx_compile_cxx11_required = xtrue; then +- if test x$ac_success = xno; then +- AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) +- fi +- else +- if test x$ac_success = xno; then +- HAVE_CXX11=0 +- AC_MSG_NOTICE([No compiler with C++11 support was found]) +- else +- HAVE_CXX11=1 +- AC_DEFINE(HAVE_CXX11,1, +- [define if the compiler supports basic C++11 syntax]) +- fi +- +- AC_SUBST(HAVE_CXX11) +- fi +-]) +diff --git a/scripts/ax_pthread.m4 b/scripts/ax_pthread.m4 +old mode 100644 +new mode 100755 +index 27f2533c..9f35d139 +--- a/scripts/ax_pthread.m4 ++++ b/scripts/ax_pthread.m4 +@@ -1,5 +1,5 @@ + # =========================================================================== +-# http://www.gnu.org/software/autoconf-archive/ax_pthread.html ++# https://www.gnu.org/software/autoconf-archive/ax_pthread.html + # =========================================================================== + # + # SYNOPSIS +@@ -14,24 +14,28 @@ + # flags that are needed. (The user can also force certain compiler + # flags/libs to be tested by setting these environment variables.) + # +-# Also sets PTHREAD_CC to any special C compiler that is needed for +-# multi-threaded programs (defaults to the value of CC otherwise). (This +-# is necessary on AIX to use the special cc_r compiler alias.) ++# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is ++# needed for multi-threaded programs (defaults to the value of CC ++# respectively CXX otherwise). (This is necessary on e.g. AIX to use the ++# special cc_r/CC_r compiler alias.) + # + # NOTE: You are assumed to not only compile your program with these flags, +-# but also link it with them as well. e.g. you should link with ++# but also to link with them as well. For example, you might link with + # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS ++# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS + # +-# If you are only building threads programs, you may wish to use these ++# If you are only building threaded programs, you may wish to use these + # variables in your default LIBS, CFLAGS, and CC: + # + # LIBS="$PTHREAD_LIBS $LIBS" + # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" ++# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" + # CC="$PTHREAD_CC" ++# CXX="$PTHREAD_CXX" + # + # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant +-# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name +-# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). ++# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to ++# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). + # + # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the + # PTHREAD_PRIO_INHERIT symbol is defined when compiling with +@@ -55,6 +59,7 @@ + # + # Copyright (c) 2008 Steven G. Johnson + # Copyright (c) 2011 Daniel Richard G. ++# Copyright (c) 2019 Marc Stevens + # + # This program is free software: you can redistribute it and/or modify it + # under the terms of the GNU General Public License as published by the +@@ -67,7 +72,7 @@ + # Public License for more details. + # + # You should have received a copy of the GNU General Public License along +-# with this program. If not, see . ++# with this program. If not, see . + # + # As a special exception, the respective Autoconf Macro's copyright owner + # gives unlimited permission to copy, distribute and modify the configure +@@ -82,35 +87,41 @@ + # modified version of the Autoconf Macro, you may extend this special + # exception to the GPL to apply to your modified version as well. + +-#serial 17 ++#serial 31 + + AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) + AC_DEFUN([AX_PTHREAD], [ + AC_REQUIRE([AC_CANONICAL_HOST]) ++AC_REQUIRE([AC_PROG_CC]) ++AC_REQUIRE([AC_PROG_SED]) + AC_LANG_PUSH([C]) + ax_pthread_ok=no + + # We used to check for pthread.h first, but this fails if pthread.h +-# requires special compiler flags (e.g. on True64 or Sequent). ++# requires special compiler flags (e.g. on Tru64 or Sequent). + # It gets checked for in the link test anyway. + + # First of all, check if the user has set any of the PTHREAD_LIBS, + # etcetera environment variables, and if threads linking works using + # them: +-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then +- save_CFLAGS="$CFLAGS" ++if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ++ ax_pthread_save_CC="$CC" ++ ax_pthread_save_CFLAGS="$CFLAGS" ++ ax_pthread_save_LIBS="$LIBS" ++ AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) ++ AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +- save_LIBS="$LIBS" + LIBS="$PTHREAD_LIBS $LIBS" +- AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) +- AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) +- AC_MSG_RESULT($ax_pthread_ok) +- if test x"$ax_pthread_ok" = xno; then ++ AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) ++ AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) ++ AC_MSG_RESULT([$ax_pthread_ok]) ++ if test "x$ax_pthread_ok" = "xno"; then + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + fi +- LIBS="$save_LIBS" +- CFLAGS="$save_CFLAGS" ++ CC="$ax_pthread_save_CC" ++ CFLAGS="$ax_pthread_save_CFLAGS" ++ LIBS="$ax_pthread_save_LIBS" + fi + + # We must check for the threads library under a number of different +@@ -118,12 +129,14 @@ fi + # (e.g. DEC) have both -lpthread and -lpthreads, where one of the + # libraries is broken (non-POSIX). + +-# Create a list of thread flags to try. Items starting with a "-" are +-# C compiler flags, and other items are library names, except for "none" +-# which indicates that we try without any flags at all, and "pthread-config" +-# which is a program returning the flags for the Pth emulation library. ++# Create a list of thread flags to try. Items with a "," contain both ++# C compiler flags (before ",") and linker flags (after ","). Other items ++# starting with a "-" are C compiler flags, and remaining items are ++# library names, except for "none" which indicates that we try without ++# any flags at all, and "pthread-config" which is a program returning ++# the flags for the Pth emulation library. + +-ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" ++ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" + + # The ordering *is* (sometimes) important. Some notes on the + # individual items follow: +@@ -132,68 +145,163 @@ ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mt + # none: in case threads are in libc; should be tried before -Kthread and + # other compiler flags to prevent continual compiler warnings + # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) +-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) +-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) +-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) +-# -pthreads: Solaris/gcc +-# -mthreads: Mingw32/gcc, Lynx/gcc ++# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 ++# (Note: HP C rejects this with "bad form for `-t' option") ++# -pthreads: Solaris/gcc (Note: HP C also rejects) + # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it +-# doesn't hurt to check since this sometimes defines pthreads too; +-# also defines -D_REENTRANT) +-# ... -mt is also the pthreads flag for HP/aCC ++# doesn't hurt to check since this sometimes defines pthreads and ++# -D_REENTRANT too), HP C (must be checked before -lpthread, which ++# is present but should not be used directly; and before -mthreads, ++# because the compiler interprets this as "-mt" + "-hreads") ++# -mthreads: Mingw32/gcc, Lynx/gcc + # pthread: Linux, etcetera + # --thread-safe: KAI C++ + # pthread-config: use pthread-config program (for GNU Pth library) + +-case "${host_cpu}-${host_os}" in +- *solaris*) ++case $host_os in ++ ++ freebsd*) ++ ++ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) ++ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ++ ++ ax_pthread_flags="-kthread lthread $ax_pthread_flags" ++ ;; ++ ++ hpux*) ++ ++ # From the cc(1) man page: "[-mt] Sets various -D flags to enable ++ # multi-threading and also sets -lpthread." ++ ++ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ++ ;; ++ ++ openedition*) ++ ++ # IBM z/OS requires a feature-test macro to be defined in order to ++ # enable POSIX threads at all, so give the user a hint if this is ++ # not set. (We don't define these ourselves, as they can affect ++ # other portions of the system API in unpredictable ways.) ++ ++ AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], ++ [ ++# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) ++ AX_PTHREAD_ZOS_MISSING ++# endif ++ ], ++ [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ++ ;; ++ ++ solaris*) + + # On Solaris (at least, for some versions), libc contains stubbed + # (non-functional) versions of the pthreads routines, so link-based +- # tests will erroneously succeed. (We need to link with -pthreads/-mt/ +- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather +- # a function called by this macro, so we could check for that, but +- # who knows whether they'll stub that too in a future libc.) So, +- # we'll just look for -pthreads and -lpthread first: ++ # tests will erroneously succeed. (N.B.: The stubs are missing ++ # pthread_cleanup_push, or rather a function called by this macro, ++ # so we could check for that, but who knows whether they'll stub ++ # that too in a future libc.) So we'll check first for the ++ # standard Solaris way of linking pthreads (-mt -lpthread). + +- ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" ++ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" + ;; ++esac + +- *-darwin*) +- ax_pthread_flags="none -pthread $ax_pthread_flags" ++# Are we compiling with Clang? ++ ++AC_CACHE_CHECK([whether $CC is Clang], ++ [ax_cv_PTHREAD_CLANG], ++ [ax_cv_PTHREAD_CLANG=no ++ # Note that Autoconf sets GCC=yes for Clang as well as GCC ++ if test "x$GCC" = "xyes"; then ++ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], ++ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ ++# if defined(__clang__) && defined(__llvm__) ++ AX_PTHREAD_CC_IS_CLANG ++# endif ++ ], ++ [ax_cv_PTHREAD_CLANG=yes]) ++ fi ++ ]) ++ax_pthread_clang="$ax_cv_PTHREAD_CLANG" ++ ++ ++# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) ++ ++# Note that for GCC and Clang -pthread generally implies -lpthread, ++# except when -nostdlib is passed. ++# This is problematic using libtool to build C++ shared libraries with pthread: ++# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 ++# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 ++# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 ++# To solve this, first try -pthread together with -lpthread for GCC ++ ++AS_IF([test "x$GCC" = "xyes"], ++ [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) ++ ++# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first ++ ++AS_IF([test "x$ax_pthread_clang" = "xyes"], ++ [ax_pthread_flags="-pthread,-lpthread -pthread"]) ++ ++ ++# The presence of a feature test macro requesting re-entrant function ++# definitions is, on some systems, a strong hint that pthreads support is ++# correctly enabled ++ ++case $host_os in ++ darwin* | hpux* | linux* | osf* | solaris*) ++ ax_pthread_check_macro="_REENTRANT" ++ ;; ++ ++ aix*) ++ ax_pthread_check_macro="_THREAD_SAFE" ++ ;; ++ ++ *) ++ ax_pthread_check_macro="--" + ;; + esac ++AS_IF([test "x$ax_pthread_check_macro" = "x--"], ++ [ax_pthread_check_cond=0], ++ [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) ++ + +-if test x"$ax_pthread_ok" = xno; then +-for flag in $ax_pthread_flags; do ++if test "x$ax_pthread_ok" = "xno"; then ++for ax_pthread_try_flag in $ax_pthread_flags; do + +- case $flag in ++ case $ax_pthread_try_flag in + none) + AC_MSG_CHECKING([whether pthreads work without any flags]) + ;; + ++ *,*) ++ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` ++ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` ++ AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) ++ ;; ++ + -*) +- AC_MSG_CHECKING([whether pthreads work with $flag]) +- PTHREAD_CFLAGS="$flag" ++ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) ++ PTHREAD_CFLAGS="$ax_pthread_try_flag" + ;; + + pthread-config) +- AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) +- if test x"$ax_pthread_config" = xno; then continue; fi ++ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) ++ AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) + PTHREAD_CFLAGS="`pthread-config --cflags`" + PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" + ;; + + *) +- AC_MSG_CHECKING([for the pthreads library -l$flag]) +- PTHREAD_LIBS="-l$flag" ++ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) ++ PTHREAD_LIBS="-l$ax_pthread_try_flag" + ;; + esac + +- save_LIBS="$LIBS" +- save_CFLAGS="$CFLAGS" +- LIBS="$PTHREAD_LIBS $LIBS" ++ ax_pthread_save_CFLAGS="$CFLAGS" ++ ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" ++ LIBS="$PTHREAD_LIBS $LIBS" + + # Check for various functions. We must include pthread.h, + # since some functions may be macros. (On the Sequent, we +@@ -204,8 +312,18 @@ for flag in $ax_pthread_flags; do + # pthread_cleanup_push because it is one of the few pthread + # functions on Solaris that doesn't have a non-functional libc stub. + # We try pthread_create on general principles. ++ + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include +- static void routine(void *a) { a = 0; } ++# if $ax_pthread_check_cond ++# error "$ax_pthread_check_macro must be defined" ++# endif ++ static void *some_global = NULL; ++ static void routine(void *a) ++ { ++ /* To avoid any unused-parameter or ++ unused-but-set-parameter warning. */ ++ some_global = a; ++ } + static void *start_routine(void *a) { return a; }], + [pthread_t th; pthread_attr_t attr; + pthread_create(&th, 0, start_routine, 0); +@@ -213,93 +331,188 @@ for flag in $ax_pthread_flags; do + pthread_attr_init(&attr); + pthread_cleanup_push(routine, 0); + pthread_cleanup_pop(0) /* ; */])], +- [ax_pthread_ok=yes], +- []) ++ [ax_pthread_ok=yes], ++ []) + +- LIBS="$save_LIBS" +- CFLAGS="$save_CFLAGS" ++ CFLAGS="$ax_pthread_save_CFLAGS" ++ LIBS="$ax_pthread_save_LIBS" + +- AC_MSG_RESULT($ax_pthread_ok) +- if test "x$ax_pthread_ok" = xyes; then +- break; +- fi ++ AC_MSG_RESULT([$ax_pthread_ok]) ++ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) + + PTHREAD_LIBS="" + PTHREAD_CFLAGS="" + done + fi + ++ ++# Clang needs special handling, because older versions handle the -pthread ++# option in a rather... idiosyncratic way ++ ++if test "x$ax_pthread_clang" = "xyes"; then ++ ++ # Clang takes -pthread; it has never supported any other flag ++ ++ # (Note 1: This will need to be revisited if a system that Clang ++ # supports has POSIX threads in a separate library. This tends not ++ # to be the way of modern systems, but it's conceivable.) ++ ++ # (Note 2: On some systems, notably Darwin, -pthread is not needed ++ # to get POSIX threads support; the API is always present and ++ # active. We could reasonably leave PTHREAD_CFLAGS empty. But ++ # -pthread does define _REENTRANT, and while the Darwin headers ++ # ignore this macro, third-party headers might not.) ++ ++ # However, older versions of Clang make a point of warning the user ++ # that, in an invocation where only linking and no compilation is ++ # taking place, the -pthread option has no effect ("argument unused ++ # during compilation"). They expect -pthread to be passed in only ++ # when source code is being compiled. ++ # ++ # Problem is, this is at odds with the way Automake and most other ++ # C build frameworks function, which is that the same flags used in ++ # compilation (CFLAGS) are also used in linking. Many systems ++ # supported by AX_PTHREAD require exactly this for POSIX threads ++ # support, and in fact it is often not straightforward to specify a ++ # flag that is used only in the compilation phase and not in ++ # linking. Such a scenario is extremely rare in practice. ++ # ++ # Even though use of the -pthread flag in linking would only print ++ # a warning, this can be a nuisance for well-run software projects ++ # that build with -Werror. So if the active version of Clang has ++ # this misfeature, we search for an option to squash it. ++ ++ AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], ++ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], ++ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown ++ # Create an alternate version of $ac_link that compiles and ++ # links in two steps (.c -> .o, .o -> exe) instead of one ++ # (.c -> exe), because the warning occurs only in the second ++ # step ++ ax_pthread_save_ac_link="$ac_link" ++ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ++ ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` ++ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ++ ax_pthread_save_CFLAGS="$CFLAGS" ++ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do ++ AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) ++ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ++ ac_link="$ax_pthread_save_ac_link" ++ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], ++ [ac_link="$ax_pthread_2step_ac_link" ++ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], ++ [break]) ++ ]) ++ done ++ ac_link="$ax_pthread_save_ac_link" ++ CFLAGS="$ax_pthread_save_CFLAGS" ++ AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ++ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ++ ]) ++ ++ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in ++ no | unknown) ;; ++ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; ++ esac ++ ++fi # $ax_pthread_clang = yes ++ ++ ++ + # Various other checks: +-if test "x$ax_pthread_ok" = xyes; then +- save_LIBS="$LIBS" +- LIBS="$PTHREAD_LIBS $LIBS" +- save_CFLAGS="$CFLAGS" ++if test "x$ax_pthread_ok" = "xyes"; then ++ ax_pthread_save_CFLAGS="$CFLAGS" ++ ax_pthread_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" ++ LIBS="$PTHREAD_LIBS $LIBS" + + # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. +- AC_MSG_CHECKING([for joinable pthread attribute]) +- attr_name=unknown +- for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do +- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], +- [int attr = $attr; return attr /* ; */])], +- [attr_name=$attr; break], +- []) +- done +- AC_MSG_RESULT($attr_name) +- if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then +- AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, +- [Define to necessary symbol if this constant +- uses a non-standard name on your system.]) +- fi ++ AC_CACHE_CHECK([for joinable pthread attribute], ++ [ax_cv_PTHREAD_JOINABLE_ATTR], ++ [ax_cv_PTHREAD_JOINABLE_ATTR=unknown ++ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], ++ [int attr = $ax_pthread_attr; return attr /* ; */])], ++ [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], ++ []) ++ done ++ ]) ++ AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ ++ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ ++ test "x$ax_pthread_joinable_attr_defined" != "xyes"], ++ [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], ++ [$ax_cv_PTHREAD_JOINABLE_ATTR], ++ [Define to necessary symbol if this constant ++ uses a non-standard name on your system.]) ++ ax_pthread_joinable_attr_defined=yes ++ ]) + +- AC_MSG_CHECKING([if more special flags are required for pthreads]) +- flag=no +- case "${host_cpu}-${host_os}" in +- *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; +- *-osf* | *-hpux*) flag="-D_REENTRANT";; +- *solaris*) +- if test "$GCC" = "yes"; then +- flag="-D_REENTRANT" +- else +- flag="-mt -D_REENTRANT" +- fi +- ;; +- esac +- AC_MSG_RESULT(${flag}) +- if test "x$flag" != xno; then +- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" +- fi ++ AC_CACHE_CHECK([whether more special flags are required for pthreads], ++ [ax_cv_PTHREAD_SPECIAL_FLAGS], ++ [ax_cv_PTHREAD_SPECIAL_FLAGS=no ++ case $host_os in ++ solaris*) ++ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ++ ;; ++ esac ++ ]) ++ AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ ++ test "x$ax_pthread_special_flags_added" != "xyes"], ++ [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ++ ax_pthread_special_flags_added=yes]) + + AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], +- ax_cv_PTHREAD_PRIO_INHERIT, [ +- AC_LINK_IFELSE([ +- AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], +- [ax_cv_PTHREAD_PRIO_INHERIT=yes], +- [ax_cv_PTHREAD_PRIO_INHERIT=no]) ++ [ax_cv_PTHREAD_PRIO_INHERIT], ++ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], ++ [[int i = PTHREAD_PRIO_INHERIT; ++ return i;]])], ++ [ax_cv_PTHREAD_PRIO_INHERIT=yes], ++ [ax_cv_PTHREAD_PRIO_INHERIT=no]) + ]) +- AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], +- AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) ++ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ ++ test "x$ax_pthread_prio_inherit_defined" != "xyes"], ++ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ++ ax_pthread_prio_inherit_defined=yes ++ ]) + +- LIBS="$save_LIBS" +- CFLAGS="$save_CFLAGS" ++ CFLAGS="$ax_pthread_save_CFLAGS" ++ LIBS="$ax_pthread_save_LIBS" + +- # More AIX lossage: must compile with xlc_r or cc_r +- if test x"$GCC" != xyes; then +- AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) +- else +- PTHREAD_CC=$CC ++ # More AIX lossage: compile with *_r variant ++ if test "x$GCC" != "xyes"; then ++ case $host_os in ++ aix*) ++ AS_CASE(["x/$CC"], ++ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], ++ [#handle absolute path differently from PATH based program lookup ++ AS_CASE(["x$CC"], ++ [x/*], ++ [ ++ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) ++ AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) ++ ], ++ [ ++ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) ++ AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) ++ ] ++ ) ++ ]) ++ ;; ++ esac + fi +-else +- PTHREAD_CC="$CC" + fi + +-AC_SUBST(PTHREAD_LIBS) +-AC_SUBST(PTHREAD_CFLAGS) +-AC_SUBST(PTHREAD_CC) ++test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" ++test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" ++ ++AC_SUBST([PTHREAD_LIBS]) ++AC_SUBST([PTHREAD_CFLAGS]) ++AC_SUBST([PTHREAD_CC]) ++AC_SUBST([PTHREAD_CXX]) + + # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +-if test x"$ax_pthread_ok" = xyes; then +- ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) ++if test "x$ax_pthread_ok" = "xyes"; then ++ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) + : + else + ax_pthread_ok=no +diff --git a/scripts/checks.m4 b/scripts/checks.m4 +index 915a5011..b9095cee 100644 +--- a/scripts/checks.m4 ++++ b/scripts/checks.m4 +@@ -21,7 +21,7 @@ AC_DEFUN([TORRENT_CHECK_XFS], [ + + AC_DEFUN([TORRENT_WITHOUT_XFS], [ + AC_ARG_WITH(xfs, +- AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]), ++ AS_HELP_STRING([--without-xfs],[do not check for XFS filesystem support]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_XFS +@@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [ + + AC_DEFUN([TORRENT_WITH_XFS], [ + AC_ARG_WITH(xfs, +- AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]), ++ AS_HELP_STRING([--with-xfs],[check for XFS filesystem support]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_XFS +@@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [ + + AC_DEFUN([TORRENT_WITHOUT_EPOLL], [ + AC_ARG_WITH(epoll, +- AC_HELP_STRING([--without-epoll], [do not check for epoll support]), ++ AS_HELP_STRING([--without-epoll],[do not check for epoll support]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_EPOLL +@@ -134,7 +134,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [ + + AC_DEFUN([TORRENT_WITH_KQUEUE], [ + AC_ARG_WITH(kqueue, +- AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]), ++ AS_HELP_STRING([--with-kqueue],[enable kqueue [[default=no]]]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE +@@ -145,7 +145,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [ + + AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ + AC_ARG_WITH(kqueue, +- AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]), ++ AS_HELP_STRING([--without-kqueue],[do not check for kqueue support]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_KQUEUE +@@ -158,7 +158,7 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ + + AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ + AC_ARG_WITH(variable-fdset, +- AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]), ++ AS_HELP_STRING([--without-variable-fdset],[do not use non-portable variable sized fd_set's]), + [ + if test "$withval" = "yes"; then + AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size) +@@ -172,14 +172,13 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ + AC_DEFUN([TORRENT_CHECK_FALLOCATE], [ + AC_MSG_CHECKING(for fallocate) + +- AC_TRY_LINK([#define _GNU_SOURCE ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE + #include +- ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0; +- ], +- [ ++ ]], [[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0; ++ ]])],[ + AC_DEFINE(HAVE_FALLOCATE, 1, Linux's fallocate supported.) + AC_MSG_RESULT(yes) +- ], [ ++ ],[ + AC_MSG_RESULT(no) + ]) + ]) +@@ -188,13 +187,12 @@ AC_DEFUN([TORRENT_CHECK_FALLOCATE], [ + AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [ + AC_MSG_CHECKING(for posix_fallocate) + +- AC_TRY_LINK([#include +- ],[ posix_fallocate(0, 0, 0); +- ], +- [ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ++ ]], [[ posix_fallocate(0, 0, 0); ++ ]])],[ + AC_DEFINE(USE_POSIX_FALLOCATE, 1, posix_fallocate supported.) + AC_MSG_RESULT(yes) +- ], [ ++ ],[ + AC_MSG_RESULT(no) + ]) + ]) +@@ -202,7 +200,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [ + + AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [ + AC_ARG_WITH(posix-fallocate, +- AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]), ++ AS_HELP_STRING([--with-posix-fallocate],[check for and use posix_fallocate to allocate files]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_POSIX_FALLOCATE +@@ -215,8 +213,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [ + + AC_MSG_CHECKING(for statvfs) + +- AC_TRY_LINK( +- [ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #if HAVE_SYS_VFS_H + #include + #endif +@@ -226,12 +223,11 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [ + #if HAVE_SYS_STATFS_H + #include + #endif +- ],[ ++ ]], [[ + struct statvfs s; fsblkcnt_t c; + statvfs("", &s); + fstatvfs(0, &s); +- ], +- [ ++ ]])],[ + AC_DEFINE(FS_STAT_FD, [fstatvfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd) + AC_DEFINE(FS_STAT_FN, [statvfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename) + AC_DEFINE(FS_STAT_STRUCT, [struct statvfs], Type of second argument to statfs function) +@@ -240,8 +236,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [ + AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_frsize)], Determine the block size) + AC_MSG_RESULT(ok) + have_stat_vfs=yes +- ], +- [ ++ ],[ + AC_MSG_RESULT(no) + have_stat_vfs=no + ]) +@@ -252,8 +247,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [ + + AC_MSG_CHECKING(for statfs) + +- AC_TRY_LINK( +- [ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #if HAVE_SYS_STATFS_H + #include + #endif +@@ -263,12 +257,11 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [ + #if HAVE_SYS_MOUNT_H + #include + #endif +- ],[ ++ ]], [[ + struct statfs s; + statfs("", &s); + fstatfs(0, &s); +- ], +- [ ++ ]])],[ + AC_DEFINE(FS_STAT_FD, [fstatfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd) + AC_DEFINE(FS_STAT_FN, [statfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename) + AC_DEFINE(FS_STAT_STRUCT, [struct statfs], Type of second argument to statfs function) +@@ -277,8 +270,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [ + AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_bsize)], Determine the block size) + AC_MSG_RESULT(ok) + have_stat_vfs=yes +- ], +- [ ++ ],[ + AC_MSG_RESULT(no) + have_stat_vfs=no + ]) +@@ -296,7 +288,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [ + + AC_DEFUN([TORRENT_WITHOUT_STATVFS], [ + AC_ARG_WITH(statvfs, +- AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]), ++ AS_HELP_STRING([--without-statvfs],[don't try to use statvfs to find free diskspace]), + [ + if test "$withval" = "yes"; then + TORRENT_CHECK_STATVFS +@@ -311,7 +303,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [ + + AC_DEFUN([TORRENT_WITHOUT_STATFS], [ + AC_ARG_WITH(statfs, +- AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]), ++ AS_HELP_STRING([--without-statfs],[don't try to use statfs to find free diskspace]), + [ + if test "$have_stat_vfs" = "no"; then + if test "$withval" = "yes"; then +@@ -333,7 +325,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [ + + AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [ + AC_ARG_WITH(address-space, +- AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]), ++ AS_HELP_STRING([--with-address-space=MB],[change the default address space size [[default=1024mb]]]), + [ + if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then + AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval]) +@@ -354,7 +346,7 @@ AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [ + + AC_DEFUN([TORRENT_WITH_FASTCGI], [ + AC_ARG_WITH(fastcgi, +- AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]), ++ AS_HELP_STRING([--with-fastcgi=PATH],[enable FastCGI RPC support (DO NOT USE)]), + [ + AC_MSG_CHECKING([for FastCGI (DO NOT USE)]) + +@@ -365,13 +357,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [ + CXXFLAGS="$CXXFLAGS" + LIBS="$LIBS -lfcgi" + +- AC_TRY_LINK( +- [ #include +- ],[ FCGX_Init(); ], +- [ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ++ ]], [[ FCGX_Init(); ]])],[ + AC_MSG_RESULT(ok) +- ], +- [ ++ ],[ + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Could not compile FastCGI test.) + ]) +@@ -382,13 +371,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [ + CXXFLAGS="$CXXFLAGS -I$withval/include" + LIBS="$LIBS -lfcgi -L$withval/lib" + +- AC_TRY_LINK( +- [ #include +- ],[ FCGX_Init(); ], +- [ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ++ ]], [[ FCGX_Init(); ]])],[ + AC_MSG_RESULT(ok) +- ], +- [ ++ ],[ + AC_MSG_RESULT(not found) + AC_MSG_ERROR(Could not compile FastCGI test.) + ]) +@@ -403,7 +389,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [ + AC_MSG_CHECKING(for XMLRPC-C) + + AC_ARG_WITH(xmlrpc-c, +- AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]), ++ AS_HELP_STRING([--with-xmlrpc-c=PATH],[enable XMLRPC-C support]), + [ + if test "$withval" = "no"; then + AC_MSG_RESULT(no) +@@ -419,12 +405,10 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [ + CXXFLAGS="$CXXFLAGS `$xmlrpc_cc_prg --cflags server-util`" + LIBS="$LIBS `$xmlrpc_cc_prg server-util --libs`" + +- AC_TRY_LINK( +- [ #include +- ],[ xmlrpc_registry_new(NULL); ], +- [ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ++ ]], [[ xmlrpc_registry_new(NULL); ]])],[ + AC_MSG_RESULT(ok) +- ], [ ++ ],[ + AC_MSG_RESULT(failed) + AC_MSG_ERROR(Could not compile XMLRPC-C test.) + ]) +@@ -466,23 +450,23 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [ + + AC_MSG_CHECKING(for pthread_setname_np type) + +- AC_TRY_LINK([ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + #include +- ],[ ++ ]], [[ + pthread_t t; + pthread_setname_np(t, "foo"); +- ],[ ++ ]])],[ + AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.) + AC_MSG_RESULT(generic) + ],[ +- AC_TRY_LINK([ ++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + #include + #include +- ],[ ++ ]],[[ + pthread_t t; + pthread_setname_np("foo"); +- ],[ ++ ]])],[ + AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.) + AC_MSG_RESULT(darwin) + ],[ +@@ -495,7 +479,7 @@ AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [ + AC_MSG_CHECKING([for pthread_setname_no]) + + AC_ARG_ENABLE(pthread-setname-np, +- AC_HELP_STRING([--disable-pthread-setname-np], [disable pthread_setname_np]), ++ AS_HELP_STRING([--disable-pthread-setname-np],[disable pthread_setname_np]), + [ + if test "$enableval" = "no"; then + AC_MSG_RESULT(disabled) +diff --git a/scripts/common.m4 b/scripts/common.m4 +index 55e8d66e..2f54402e 100644 +--- a/scripts/common.m4 ++++ b/scripts/common.m4 +@@ -1,6 +1,7 @@ + AC_DEFUN([TORRENT_WITH_SYSROOT], [ + AC_ARG_WITH(sysroot, +- AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]), ++ AS_HELP_STRING([--with-sysroot=PATH], ++ [compile and link with a specific sysroot]), + [ + AC_MSG_CHECKING(for sysroot) + +@@ -22,7 +23,8 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [ + + AC_DEFUN([TORRENT_ENABLE_ARCH], [ + AC_ARG_ENABLE(arch, +- AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]), ++ AS_HELP_STRING([--enable-arch=ARCH], ++ [comma seprated list of architectures to compile for]), + [ + AC_MSG_CHECKING(for target architectures) + +@@ -82,7 +84,8 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [ + + AC_DEFUN([TORRENT_MINCORE], [ + AC_ARG_ENABLE(mincore, +- AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]), ++ AS_HELP_STRING([--disable-mincore], ++ [disable mincore check [[default=enable]]]), + [ + if test "$enableval" = "yes"; then + TORRENT_MINCORE_SIGNEDNESS() +@@ -174,7 +177,8 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [ + + AC_DEFUN([TORRENT_ENABLE_ALIGNED], [ + AC_ARG_ENABLE(aligned, +- AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]), ++ AS_HELP_STRING([--enable-aligned], ++ [enable alignment safe code [[default=check]]]), + [ + if test "$enableval" = "yes"; then + AC_DEFINE(USE_ALIGNED, 1, Require byte alignment) +@@ -189,7 +193,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [ + AC_MSG_CHECKING([if instrumentation should be included]) + + AC_ARG_ENABLE(instrumentation, +- AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]), ++ AS_HELP_STRING([--disable-instrumentation], ++ [disable instrumentation [[default=enabled]]]), + [ + if test "$enableval" = "yes"; then + AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation) +@@ -206,7 +211,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [ + + AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [ + AC_ARG_ENABLE(interrupt-socket, +- AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]), ++ AS_HELP_STRING([--enable-interrupt-socket], ++ [enable interrupt socket [[default=no]]]), + [ + if test "$enableval" = "yes"; then + AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill) +@@ -214,3 +220,14 @@ AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [ + ] + ) + ]) ++ ++AC_DEFUN([TORRENT_DISABLE_IPV6], [ ++ AC_ARG_ENABLE(ipv6, ++ AS_HELP_STRING([--enable-ipv6], ++ [enable ipv6 [[default=no]]]), ++ [ ++ if test "$enableval" = "yes"; then ++ AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff) ++ fi ++ ]) ++]) +diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4 +index 9a361bed..bc1572a3 100644 +--- a/scripts/rak_compiler.m4 ++++ b/scripts/rak_compiler.m4 +@@ -26,7 +26,7 @@ AC_DEFUN([RAK_CHECK_CXXFLAGS], [ + + AC_DEFUN([RAK_ENABLE_DEBUG], [ + AC_ARG_ENABLE(debug, +- AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]), ++ AS_HELP_STRING([--enable-debug],[enable debug information [[default=yes]]]), + [ + if test "$enableval" = "yes"; then + CXXFLAGS="$CXXFLAGS -g -DDEBUG" +@@ -41,7 +41,7 @@ AC_DEFUN([RAK_ENABLE_DEBUG], [ + + AC_DEFUN([RAK_ENABLE_WERROR], [ + AC_ARG_ENABLE(werror, +- AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flags [[default -Wall only]]]), ++ AS_HELP_STRING([--enable-werror],[enable the -Werror and -Wall flags [[default -Wall only]]]), + [ + if test "$enableval" = "yes"; then + CXXFLAGS="$CXXFLAGS -Werror -Wall" +@@ -54,7 +54,7 @@ AC_DEFUN([RAK_ENABLE_WERROR], [ + + AC_DEFUN([RAK_ENABLE_EXTRA_DEBUG], [ + AC_ARG_ENABLE(extra-debug, +- AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]), ++ AS_HELP_STRING([--enable-extra-debug],[enable extra debugging checks [[default=no]]]), + [ + if test "$enableval" = "yes"; then + AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.) +diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4 +deleted file mode 100644 +index 0db61b83..00000000 +--- a/scripts/rak_cxx.m4 ++++ /dev/null +@@ -1,14 +0,0 @@ +-AC_DEFUN([RAK_CHECK_CXX11], [ +- AC_ARG_ENABLE([c++0x], +- AC_HELP_STRING([--enable-c++0x], [compile with C++0x (unsupported)]), +- [ +- if test "$enableval" = "yes"; then +- AX_CXX_COMPILE_STDCXX_0X +- else +- AX_CXX_COMPILE_STDCXX_11(noext) +- fi +- ],[ +- AX_CXX_COMPILE_STDCXX_11(noext) +- ] +- ) +-]) 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 000000000..b9378f503 --- /dev/null +++ b/meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch @@ -0,0 +1,29 @@ +From eca577e2a29d64251b5df1c69be53c5b1ffe6bde Mon Sep 17 00:00:00 2001 +From: Jari Sundell +Date: Thu, 8 Sep 2022 05:08:44 +0900 +Subject: [PATCH] Create FUNDING.yml + +--- + .github/FUNDING.yml | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + create mode 100644 .github/FUNDING.yml + +diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml +new file mode 100644 +index 00000000..ad5998e8 +--- /dev/null ++++ b/.github/FUNDING.yml +@@ -0,0 +1,13 @@ ++# These are supported funding model platforms ++ ++github: [rakshasa] ++patreon: rtorrent ++open_collective: # Replace with a single Open Collective username ++ko_fi: # Replace with a single Ko-fi username ++tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel ++community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry ++liberapay: # Replace with a single Liberapay username ++issuehunt: # Replace with a single IssueHunt username ++otechie: # Replace with a single Otechie username ++lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry ++custom: ['https://rakshasa.github.io/rtorrent/donate.html'] diff --git a/meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb b/meta-oe/recipes-connectivity/libtorrent/libtorrent_git.bb index fec05571d..70c173be5 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" DEPENDS = "zlib libsigc++-2.0 openssl cppunit" -SRC_URI = "git://github.com/rakshasa/libtorrent;branch=master;protocol=https" -SRCREV = "e60f222241319aaae482789517ad00ae9344bd13" +SRC_URI = "git://github.com/rakshasa/libtorrent;branch=master;protocol=https \ + file://0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch \ + file://0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch \ + file://0003-Add-space-to-fmt-str-in-log_gz_file_write.patch \ + file://0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch \ + file://0005-Disable-extents-test-to-pass-TravisCI-See-11.patch \ + file://0006-Bumped-version-to-0.13.7.patch \ + file://0007-Added-support-for-openssl-1.1.patch \ + file://0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch \ + file://0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch \ + file://0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch \ + file://0011-Strip-tags-also-when-displaying-info-on-failed-track.patch \ + file://0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch \ + file://0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch \ + file://0014-If-during-socket-creation-AF_INET6-failes-initialize.patch \ + file://0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch \ + file://0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch \ + file://0017-increase-piece-length-max.patch \ + file://0018-Set-max-piece-size-512mb.patch \ + file://0019-Fixed-compiler-warning.patch \ + file://0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch \ + file://0021-Fixed-diffie-hellman-implementation.patch \ + file://0022-Increased-max-timeout-for-tracker-requests.patch \ + file://0023-Close-log-files-when-reusing-a-name.patch \ + file://0024-Bumped-to-version-0.13.8.patch \ + file://0025-Allow-logs-to-be-appended-rather-than-overwritten.patch \ + file://0026-Removed-log-append-function.-Added-append-parameter-.patch \ + file://0027-Backport-changes-from-feature-bind.-200.patch \ + file://0028-libtorrent.pc.in-add-Libs.Private-202.patch \ + file://0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch \ + file://0030-Fix-compiler-warnings.-204.patch \ + file://0031-Fix-log-format-so-GCC-can-check-it.-205.patch \ + file://0032-Consolidate-make-script-to-optimize-build.-206.patch \ + file://0033-Refactor-make-process.-207.patch \ + file://0034-Changes-automake-required-files.patch \ + file://0035-Replaced-custom-execinfo-autoconf-test.patch \ + file://0036-Added-option-to-disable-pthread_setname_np.patch \ + file://0037-Improved-backtrace-error-checking.patch \ + file://0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch \ + file://0039-Added-disable-execinfo-option-to-configure.patch \ + file://0040-Detect-ip-address.patch \ + file://0041-Added-ipv6-options.patch \ + file://0042-Removed-obsolete-files.patch \ + file://0043-Updated-and-cleaned-up-automake.-224.patch \ + file://0044-Create-FUNDING.yml.patch \ + " +SRCREV = "c167c5a9e0bcf0df23ae5efd91396aae0e37eb87" CVE_STATUS[CVE-2009-1760] = "backported-patch: patched in our product" -PV = "0.13.8+git${SRCPV}" +PV = "1" S = "${WORKDIR}/git"