--- /srv/reproducible-results/rbuild-debian/r-b-build.JbqcmNpu/b1/libtorrent-rasterbar_2.0.11-1_amd64.changes +++ /srv/reproducible-results/rbuild-debian/r-b-build.JbqcmNpu/b2/libtorrent-rasterbar_2.0.11-1_amd64.changes ├── Files │ @@ -1,7 +1,7 @@ │ │ 1e537d9298a8b265e97c6e12e4bbe431 366364 libdevel optional libtorrent-rasterbar-dev_2.0.11-1_amd64.deb │ - 154672e3a1328e0a538de68f3f4f7b17 1670092 doc optional libtorrent-rasterbar-doc_2.0.11-1_all.deb │ + 2b74ce5e6c42f371c1f92943b39c7030 1672888 doc optional libtorrent-rasterbar-doc_2.0.11-1_all.deb │ f708eb6cbdf3293cbba03dbfb39b5940 51377760 debug optional libtorrent-rasterbar2.0t64-dbgsym_2.0.11-1_amd64.deb │ 87879df423b6afeccd9836ad9bbc4d0a 1671596 libs optional libtorrent-rasterbar2.0t64_2.0.11-1_amd64.deb │ 5e77e86f716edac734a3cce52b3064e4 13376360 debug optional python3-libtorrent-dbgsym_2.0.11-1_amd64.deb │ bf34d1de7eca57dc9c82e659d13d48af 711572 python optional python3-libtorrent_2.0.11-1_amd64.deb ├── libtorrent-rasterbar-doc_2.0.11-1_all.deb │ ├── file list │ │ @@ -1,3 +1,3 @@ │ │ -rw-r--r-- 0 0 0 4 2025-01-28 14:33:12.000000 debian-binary │ │ --rw-r--r-- 0 0 0 3632 2025-01-28 14:33:12.000000 control.tar.xz │ │ --rw-r--r-- 0 0 0 1666268 2025-01-28 14:33:12.000000 data.tar.xz │ │ +-rw-r--r-- 0 0 0 3628 2025-01-28 14:33:12.000000 control.tar.xz │ │ +-rw-r--r-- 0 0 0 1669068 2025-01-28 14:33:12.000000 data.tar.xz │ ├── control.tar.xz │ │ ├── control.tar │ │ │ ├── ./control │ │ │ │ @@ -1,13 +1,13 @@ │ │ │ │ Package: libtorrent-rasterbar-doc │ │ │ │ Source: libtorrent-rasterbar │ │ │ │ Version: 2.0.11-1 │ │ │ │ Architecture: all │ │ │ │ Maintainer: Christian Marillat │ │ │ │ -Installed-Size: 5773 │ │ │ │ +Installed-Size: 5941 │ │ │ │ Section: doc │ │ │ │ Priority: optional │ │ │ │ Multi-Arch: foreign │ │ │ │ Homepage: https://libtorrent.org/ │ │ │ │ Description: Documentation for libtorrent-rasterbar │ │ │ │ Bittorrent library by Rasterbar Software (Arvid Norberg). │ │ │ │ libtorrent-rasterbar is a C++ library that aims to be a good alternative to │ │ │ ├── ./md5sums │ │ │ │ ├── ./md5sums │ │ │ │ │┄ Files differ │ ├── data.tar.xz │ │ ├── data.tar │ │ │ ├── file list │ │ │ │ @@ -73,43 +73,43 @@ │ │ │ │ -rw-r--r-- 0 root (0) root (0) 428298 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/img/troubleshooting.png │ │ │ │ -rw-r--r-- 0 root (0) root (0) 46281 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/img/troubleshooting_thumb.png │ │ │ │ -rw-r--r-- 0 root (0) root (0) 243 2025-01-28 10:57:42.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/img/utp_stack.diagram │ │ │ │ -rw-r--r-- 0 root (0) root (0) 2007 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/img/utp_stack.png │ │ │ │ -rw-r--r-- 0 root (0) root (0) 1156 2025-01-28 10:57:42.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/img/write_disk_buffers.diagram │ │ │ │ -rw-r--r-- 0 root (0) root (0) 9631 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/img/write_disk_buffers.png │ │ │ │ -rw-r--r-- 0 root (0) root (0) 9768 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/index.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 144610 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/manual-ref.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 144603 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/manual-ref.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 9650 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/projects.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 22814 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/python_binding.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 33687 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Add_Torrent.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 256772 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Alerts.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 27437 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Bdecoding.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 25856 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Bencoding.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 88949 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Core.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 43859 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Create_Torrents.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 50915 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Custom_Storage.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 137008 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Custom_Storage.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 24960 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-DHT.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 48763 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Error_Codes.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 13261 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Filter.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 12804 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-PeerClass.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 68487 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Plugins.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 9618 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Resume_Data.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 102476 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Session.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 102455 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Session.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 169276 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Settings.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 9742 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Stats.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 56856 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Storage.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 129808 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Torrent_Handle.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 55640 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Torrent_Info.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 48385 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Torrent_Status.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 16462 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Trackers.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 56848 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Storage.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 129801 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Torrent_Handle.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 55629 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Torrent_Info.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 48392 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Torrent_Status.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 16461 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Trackers.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 25530 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Utility.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 9129 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-ed25519.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 34353 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/reference.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 29242 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/security-audit.html │ │ │ │ --rw-r--r-- 0 root (0) root (0) 1274792 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/single-page-ref.html │ │ │ │ +-rw-r--r-- 0 root (0) root (0) 1360844 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/single-page-ref.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 10121 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/streaming.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 8807 2025-01-28 10:57:42.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/style.css │ │ │ │ -rw-r--r-- 0 root (0) root (0) 522888 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/todo.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 3023 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/troubleshooting.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 25162 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/tuning-ref.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 132630 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/tutorial-ref.html │ │ │ │ -rw-r--r-- 0 root (0) root (0) 16383 2025-01-28 14:33:12.000000 ./usr/share/doc/libtorrent-rasterbar-doc/html/udp_tracker_protocol.html │ │ │ ├── ./usr/share/doc/libtorrent-rasterbar-doc/html/manual-ref.html │ │ │ │ @@ -115,15 +115,15 @@ │ │ │ │
  • main loop (see session)

    │ │ │ │
    │ │ │ │ │ │ │ │
    │ │ │ │
  • │ │ │ │
  • save resume data for all torrent_handles (optional, see │ │ │ │ save_resume_data())

    │ │ │ │
  • │ │ │ │
  • save session state (see session_state() and write_session_params())

    │ │ │ ├── ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Add_Torrent.html │ │ │ │ @@ -28,65 +28,23 @@ │ │ │ │ 2.0.11 │ │ │ │ │ │ │ │ │ │ │ │

    home

    │ │ │ │
    │ │ │ │

    Table of contents

    │ │ │ │
    │ │ │ │ -[report issue]
    │ │ │ │ -

    client_data_t

    │ │ │ │ -

    Declared in "libtorrent/client_data.hpp"

    │ │ │ │ -

    A thin wrapper around a void pointer used as "user data". i.e. an opaque │ │ │ │ -cookie passed in to libtorrent and returned on demand. It adds type-safety by │ │ │ │ -requiring the same type be requested out of it as was assigned to it.

    │ │ │ │ -
    │ │ │ │ -struct client_data_t
    │ │ │ │ -{
    │ │ │ │ -   client_data_t () = default;
    │ │ │ │ -   explicit client_data_t (T* v);
    │ │ │ │ -   client_data_t& operator= (T* v);
    │ │ │ │ -   explicit operator T () const;
    │ │ │ │ -   T* get () const;
    │ │ │ │ -   client_data_t& operator= (void*) = delete;
    │ │ │ │ -   operator void const* () const = delete;
    │ │ │ │ -   operator void* () const = delete;
    │ │ │ │ -   client_data_t& operator= (void const*) = delete;
    │ │ │ │ -
    │ │ │ │ -   template <typename T, typename U  = typename std::enable_if<std::is_pointer<T>::value>::type>
    │ │ │ │ -};
    │ │ │ │ -
    │ │ │ │ -[report issue]
    │ │ │ │ -

    client_data_t()

    │ │ │ │ -
    │ │ │ │ -client_data_t () = default;
    │ │ │ │ -
    │ │ │ │ -

    construct a nullptr client data

    │ │ │ │ - │ │ │ │ - │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    const*() void*() operator=()

    │ │ │ │ -
    │ │ │ │ -client_data_t& operator= (void*) = delete;
    │ │ │ │ -operator void const* () const = delete;
    │ │ │ │ -operator void* () const = delete;
    │ │ │ │ -client_data_t& operator= (void const*) = delete;
    │ │ │ │ -
    │ │ │ │ -

    we don't allow type-unsafe operations

    │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -
    │ │ │ │ +[report issue]
    │ │ │ │

    add_torrent_params

    │ │ │ │

    Declared in "libtorrent/add_torrent_params.hpp"

    │ │ │ │

    The add_torrent_params contains all the information in a .torrent file │ │ │ │ along with all information necessary to add that torrent to a session. │ │ │ │ The key fields when adding a torrent are:

    │ │ │ │
      │ │ │ │
    • ti - the immutable info-dict part of the torrent
    • │ │ │ │ @@ -399,14 +357,56 @@ │ │ │ │ [report issue]
      │ │ │ │
      last_download last_upload
      │ │ │ │
      the posix time of the last time payload was received or sent for this │ │ │ │ torrent, respectively. A value of 0 means we don't know when we last │ │ │ │ uploaded or downloaded, or we have never uploaded or downloaded any │ │ │ │ payload for this torrent.
      │ │ │ │
      │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    client_data_t

    │ │ │ │ +

    Declared in "libtorrent/client_data.hpp"

    │ │ │ │ +

    A thin wrapper around a void pointer used as "user data". i.e. an opaque │ │ │ │ +cookie passed in to libtorrent and returned on demand. It adds type-safety by │ │ │ │ +requiring the same type be requested out of it as was assigned to it.

    │ │ │ │ +
    │ │ │ │ +struct client_data_t
    │ │ │ │ +{
    │ │ │ │ +   client_data_t () = default;
    │ │ │ │ +   explicit client_data_t (T* v);
    │ │ │ │ +   client_data_t& operator= (T* v);
    │ │ │ │ +   T* get () const;
    │ │ │ │ +   explicit operator T () const;
    │ │ │ │ +   client_data_t& operator= (void const*) = delete;
    │ │ │ │ +   client_data_t& operator= (void*) = delete;
    │ │ │ │ +   operator void const* () const = delete;
    │ │ │ │ +   operator void* () const = delete;
    │ │ │ │ +
    │ │ │ │ +   template <typename T, typename U  = typename std::enable_if<std::is_pointer<T>::value>::type>
    │ │ │ │ +};
    │ │ │ │ +
    │ │ │ │ +[report issue]
    │ │ │ │ +

    client_data_t()

    │ │ │ │ +
    │ │ │ │ +client_data_t () = default;
    │ │ │ │ +
    │ │ │ │ +

    construct a nullptr client data

    │ │ │ │ + │ │ │ │ + │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    const*() void*() operator=()

    │ │ │ │ +
    │ │ │ │ +client_data_t& operator= (void const*) = delete;
    │ │ │ │ +client_data_t& operator= (void*) = delete;
    │ │ │ │ +operator void const* () const = delete;
    │ │ │ │ +operator void* () const = delete;
    │ │ │ │ +
    │ │ │ │ +

    we don't allow type-unsafe operations

    │ │ │ │ +
    │ │ │ │
    │ │ │ │ │ │ │ │
    │ │ │ │ │ │ │ │
    │ │ │ │
    │ │ │ │
  • │ │ │ │
  • torrent_plugin │ │ │ │
  • │ │ │ │
  • peer_plugin │ │ │ │
  • │ │ │ │
  • crypto_plugin │ │ │ │
  • │ │ │ │ -
  • create_smart_ban_plugin()
  • │ │ │ │ -
  • create_ut_pex_plugin()
  • │ │ │ │ +
  • create_ut_pex_plugin()
  • │ │ │ │ +
  • create_smart_ban_plugin()
  • │ │ │ │
  • create_ut_metadata_plugin()
  • │ │ │ │ │ │ │ │ │ │ │ │

    libtorrent has a plugin interface for implementing extensions to the protocol. │ │ │ │ These can be general extensions for transferring metadata or peer exchange │ │ │ │ extensions, or it could be used to provide a way to customize the protocol │ │ │ │ to fit a particular (closed) network.

    │ │ │ │ @@ -190,50 +190,50 @@ │ │ │ │ connection object, to be used by plugins. This is a low level interface that │ │ │ │ may not be stable across libtorrent versions

    │ │ │ │
    │ │ │ │  struct peer_connection_handle
    │ │ │ │  {
    │ │ │ │     explicit peer_connection_handle (std::weak_ptr<peer_connection> impl);
    │ │ │ │     connection_type type () const;
    │ │ │ │ -   void add_extension (std::shared_ptr<peer_plugin>);
    │ │ │ │     peer_plugin const* find_plugin (string_view type) const;
    │ │ │ │ +   void add_extension (std::shared_ptr<peer_plugin>);
    │ │ │ │     bool is_seed () const;
    │ │ │ │     bool upload_only () const;
    │ │ │ │     bool has_piece (piece_index_t i) const;
    │ │ │ │     peer_id const& pid () const;
    │ │ │ │ -   bool is_interesting () const;
    │ │ │ │     bool is_choked () const;
    │ │ │ │ -   bool is_peer_interested () const;
    │ │ │ │ +   bool is_interesting () const;
    │ │ │ │     bool has_peer_choked () const;
    │ │ │ │ +   bool is_peer_interested () const;
    │ │ │ │     void maybe_unchoke_this_peer ();
    │ │ │ │     void choke_this_peer ();
    │ │ │ │     void get_peer_info (peer_info& p) const;
    │ │ │ │     torrent_handle associated_torrent () const;
    │ │ │ │ -   tcp::endpoint local_endpoint () const;
    │ │ │ │     tcp::endpoint const& remote () const;
    │ │ │ │ +   tcp::endpoint local_endpoint () const;
    │ │ │ │ +   bool is_connecting () const;
    │ │ │ │ +   bool is_disconnecting () const;
    │ │ │ │     void disconnect (error_code const& ec, operation_t op
    │ │ │ │        , disconnect_severity_t = peer_connection_interface::normal);
    │ │ │ │ -   bool is_connecting () const;
    │ │ │ │     bool is_outgoing () const;
    │ │ │ │ -   bool is_disconnecting () const;
    │ │ │ │ -   bool on_local_network () const;
    │ │ │ │     bool ignore_unchoke_slots () const;
    │ │ │ │ +   bool on_local_network () const;
    │ │ │ │     bool failed () const;
    │ │ │ │ -   bool should_log (peer_log_alert::direction_t direction) const;
    │ │ │ │     void peer_log (peer_log_alert::direction_t direction
    │ │ │ │        , char const* event, char const* fmt = "", ...) const TORRENT_FORMAT(4,5);
    │ │ │ │ +   bool should_log (peer_log_alert::direction_t direction) const;
    │ │ │ │     bool can_disconnect (error_code const& ec) const;
    │ │ │ │     bool has_metadata () const;
    │ │ │ │     bool in_handshake () const;
    │ │ │ │     void send_buffer (char const* begin, int size);
    │ │ │ │ -   time_point time_of_last_unchoke () const;
    │ │ │ │     std::time_t last_seen_complete () const;
    │ │ │ │ +   time_point time_of_last_unchoke () const;
    │ │ │ │     bool operator== (peer_connection_handle const& o) const;
    │ │ │ │ -   bool operator!= (peer_connection_handle const& o) const;
    │ │ │ │     bool operator< (peer_connection_handle const& o) const;
    │ │ │ │ +   bool operator!= (peer_connection_handle const& o) const;
    │ │ │ │     std::shared_ptr<peer_connection> native_handle () const;
    │ │ │ │  };
    │ │ │ │  
    │ │ │ │ [report issue] │ │ │ │
    │ │ │ │

    bt_peer_connection_handle

    │ │ │ │

    Declared in "libtorrent/peer_connection_handle.hpp"

    │ │ │ │ @@ -243,16 +243,16 @@ │ │ │ │
    │ │ │ │  struct bt_peer_connection_handle : peer_connection_handle
    │ │ │ │  {
    │ │ │ │     explicit bt_peer_connection_handle (peer_connection_handle pc);
    │ │ │ │     bool packet_finished () const;
    │ │ │ │     bool support_extensions () const;
    │ │ │ │     bool supports_encryption () const;
    │ │ │ │ -   void switch_send_crypto (std::shared_ptr<crypto_plugin> crypto);
    │ │ │ │     void switch_recv_crypto (std::shared_ptr<crypto_plugin> crypto);
    │ │ │ │ +   void switch_send_crypto (std::shared_ptr<crypto_plugin> crypto);
    │ │ │ │     std::shared_ptr<bt_peer_connection> native_handle () const;
    │ │ │ │  };
    │ │ │ │  
    │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    plugin

    │ │ │ │

    Declared in "libtorrent/extensions.hpp"

    │ │ │ │ @@ -415,19 +415,19 @@ │ │ │ │

    Torrent plugins are associated with a single torrent and have a number │ │ │ │ of functions called at certain events. Many of its functions have the │ │ │ │ ability to change or override the default libtorrent behavior.

    │ │ │ │
    │ │ │ │  struct torrent_plugin
    │ │ │ │  {
    │ │ │ │     virtual std::shared_ptr<peer_plugin> new_connection (peer_connection_handle const&);
    │ │ │ │ -   virtual void on_piece_failed (piece_index_t);
    │ │ │ │     virtual void on_piece_pass (piece_index_t);
    │ │ │ │ +   virtual void on_piece_failed (piece_index_t);
    │ │ │ │     virtual void tick ();
    │ │ │ │ -   virtual bool on_resume ();
    │ │ │ │     virtual bool on_pause ();
    │ │ │ │ +   virtual bool on_resume ();
    │ │ │ │     virtual void on_files_checked ();
    │ │ │ │     virtual void on_state (torrent_status::state_t);
    │ │ │ │     virtual void on_add_peer (tcp::endpoint const&,
    │ │ │ │        peer_source_flags_t, add_peer_flags_t);
    │ │ │ │  
    │ │ │ │     static constexpr add_peer_flags_t first_time  = 1_bit;
    │ │ │ │     static constexpr add_peer_flags_t filtered  = 2_bit;
    │ │ │ │ @@ -451,36 +451,36 @@
    │ │ │ │  to it, use weak_ptr.

    │ │ │ │

    If this function throws an exception, the connection will be closed.

    │ │ │ │ │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    on_piece_pass() on_piece_failed()

    │ │ │ │
    │ │ │ │ -virtual void on_piece_failed (piece_index_t);
    │ │ │ │  virtual void on_piece_pass (piece_index_t);
    │ │ │ │ +virtual void on_piece_failed (piece_index_t);
    │ │ │ │  
    │ │ │ │

    These hooks are called when a piece passes the hash check or fails the hash │ │ │ │ check, respectively. The index is the piece index that was downloaded. │ │ │ │ It is possible to access the list of peers that participated in sending the │ │ │ │ piece through the torrent and the piece_picker.

    │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    tick()

    │ │ │ │
    │ │ │ │  virtual void tick ();
    │ │ │ │  
    │ │ │ │

    This hook is called approximately once per second. It is a way of making it │ │ │ │ easy for plugins to do timed events, for sending messages or whatever.

    │ │ │ │ - │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    on_resume() on_pause()

    │ │ │ │ + │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    on_pause() on_resume()

    │ │ │ │
    │ │ │ │ -virtual bool on_resume ();
    │ │ │ │  virtual bool on_pause ();
    │ │ │ │ +virtual bool on_resume ();
    │ │ │ │  
    │ │ │ │

    These hooks are called when the torrent is paused and resumed respectively. │ │ │ │ The return value indicates if the event was handled. A return value of │ │ │ │ true indicates that it was handled, and no other plugin after this one │ │ │ │ will have this hook function called, and the standard handler will also not be │ │ │ │ invoked. So, returning true effectively overrides the standard behavior of │ │ │ │ pause or resume.

    │ │ │ │ @@ -545,51 +545,51 @@ │ │ │ │ { │ │ │ │ virtual string_view type () const; │ │ │ │ virtual void add_handshake (entry&); │ │ │ │ virtual void on_disconnect (error_code const&); │ │ │ │ virtual void on_connected (); │ │ │ │ virtual bool on_handshake (span<char const>); │ │ │ │ virtual bool on_extension_handshake (bdecode_node const&); │ │ │ │ - virtual bool on_have_none (); │ │ │ │ - virtual bool on_not_interested (); │ │ │ │ - virtual bool on_allowed_fast (piece_index_t); │ │ │ │ - virtual bool on_request (peer_request const&); │ │ │ │ virtual bool on_bitfield (bitfield const& /*bitfield*/); │ │ │ │ - virtual bool on_dont_have (piece_index_t); │ │ │ │ + virtual bool on_not_interested (); │ │ │ │ + virtual bool on_have_none (); │ │ │ │ virtual bool on_choke (); │ │ │ │ virtual bool on_have_all (); │ │ │ │ - virtual bool on_unchoke (); │ │ │ │ + virtual bool on_allowed_fast (piece_index_t); │ │ │ │ virtual bool on_interested (); │ │ │ │ + virtual bool on_dont_have (piece_index_t); │ │ │ │ virtual bool on_have (piece_index_t); │ │ │ │ + virtual bool on_unchoke (); │ │ │ │ + virtual bool on_request (peer_request const&); │ │ │ │ virtual bool on_piece (peer_request const& /*piece*/ │ │ │ │ , span<char const> /*buf*/); │ │ │ │ - virtual bool on_reject (peer_request const&); │ │ │ │ - virtual bool on_cancel (peer_request const&); │ │ │ │ virtual bool on_suggest (piece_index_t); │ │ │ │ - virtual void sent_request (peer_request const&); │ │ │ │ - virtual void sent_allow_fast (piece_index_t); │ │ │ │ - virtual void sent_suggest (piece_index_t); │ │ │ │ - virtual void sent_cancel (peer_request const&); │ │ │ │ - virtual void sent_choke (); │ │ │ │ + virtual bool on_cancel (peer_request const&); │ │ │ │ + virtual bool on_reject (peer_request const&); │ │ │ │ virtual void sent_reject_request (peer_request const&); │ │ │ │ + virtual void sent_choke (); │ │ │ │ + virtual void sent_cancel (peer_request const&); │ │ │ │ + virtual void sent_allow_fast (piece_index_t); │ │ │ │ virtual void sent_have_none (); │ │ │ │ virtual void sent_have_all (); │ │ │ │ - virtual void sent_unchoke (); │ │ │ │ + virtual void sent_suggest (piece_index_t); │ │ │ │ + virtual void sent_request (peer_request const&); │ │ │ │ virtual void sent_piece (peer_request const&); │ │ │ │ - virtual void sent_not_interested (); │ │ │ │ virtual void sent_have (piece_index_t); │ │ │ │ + virtual void sent_not_interested (); │ │ │ │ virtual void sent_interested (); │ │ │ │ + virtual void sent_unchoke (); │ │ │ │ virtual void sent_payload (int /* bytes */); │ │ │ │ virtual bool can_disconnect (error_code const& /*ec*/); │ │ │ │ virtual bool on_extended (int /*length*/, int /*msg*/, │ │ │ │ span<char const> /*body*/); │ │ │ │ virtual bool on_unknown_message (int /*length*/, int /*msg*/, │ │ │ │ span<char const> /*body*/); │ │ │ │ - virtual void on_piece_failed (piece_index_t); │ │ │ │ virtual void on_piece_pass (piece_index_t); │ │ │ │ + virtual void on_piece_failed (piece_index_t); │ │ │ │ virtual void tick (); │ │ │ │ virtual bool write_request (peer_request const&); │ │ │ │ }; │ │ │ │ │ │ │ │ [report issue]
    │ │ │ │

    type()

    │ │ │ │
    │ │ │ │ @@ -639,39 +639,39 @@
    │ │ │ │  virtual bool on_extension_handshake (bdecode_node const&);
    │ │ │ │  
    │ │ │ │

    called when the extension handshake from the other end is received │ │ │ │ if this returns false, it means that this extension isn't │ │ │ │ supported by this peer. It will result in this peer_plugin │ │ │ │ being removed from the peer_connection and destructed. │ │ │ │ this is not called for web seeds

    │ │ │ │ - │ │ │ │ + │ │ │ │ + │ │ │ │ │ │ │ │ + │ │ │ │ + │ │ │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ - │ │ │ │ │ │ │ │ - │ │ │ │ + │ │ │ │ + │ │ │ │ │ │ │ │ - │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    on_request() on_choke() on_have_none() on_interested() on_unchoke() on_bitfield() on_allowed_fast() on_have() on_have_all() on_dont_have() on_not_interested()

    │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    on_have() on_unchoke() on_choke() on_request() on_not_interested() on_have_none() on_allowed_fast() on_bitfield() on_interested() on_have_all() on_dont_have()

    │ │ │ │
    │ │ │ │ -virtual bool on_have_none ();
    │ │ │ │ -virtual bool on_not_interested ();
    │ │ │ │ -virtual bool on_allowed_fast (piece_index_t);
    │ │ │ │ -virtual bool on_request (peer_request const&);
    │ │ │ │  virtual bool on_bitfield (bitfield const& /*bitfield*/);
    │ │ │ │ -virtual bool on_dont_have (piece_index_t);
    │ │ │ │ +virtual bool on_not_interested ();
    │ │ │ │ +virtual bool on_have_none ();
    │ │ │ │  virtual bool on_choke ();
    │ │ │ │  virtual bool on_have_all ();
    │ │ │ │ -virtual bool on_unchoke ();
    │ │ │ │ +virtual bool on_allowed_fast (piece_index_t);
    │ │ │ │  virtual bool on_interested ();
    │ │ │ │ +virtual bool on_dont_have (piece_index_t);
    │ │ │ │  virtual bool on_have (piece_index_t);
    │ │ │ │ +virtual bool on_unchoke ();
    │ │ │ │ +virtual bool on_request (peer_request const&);
    │ │ │ │  
    │ │ │ │

    returning true from any of the message handlers │ │ │ │ indicates that the plugin has handled the message. │ │ │ │ it will break the plugin chain traversing and not let │ │ │ │ anyone else handle the message, including the default │ │ │ │ handler.

    │ │ │ │ [report issue]
    │ │ │ │ @@ -683,27 +683,27 @@ │ │ │ │ │ │ │ │

    This function is called when the peer connection is receiving │ │ │ │ a piece. buf points (non-owning pointer) to the data in an │ │ │ │ internal immutable disk buffer. The length of the data is specified │ │ │ │ in the length member of the piece parameter. │ │ │ │ returns true to indicate that the piece is handled and the │ │ │ │ rest of the logic should be ignored.

    │ │ │ │ - │ │ │ │ │ │ │ │ - │ │ │ │ + │ │ │ │ + │ │ │ │ │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    sent_interested() sent_not_interested() sent_piece() sent_unchoke() sent_have()

    │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    sent_not_interested() sent_have() sent_interested() sent_unchoke() sent_piece()

    │ │ │ │
    │ │ │ │ -virtual void sent_unchoke ();
    │ │ │ │  virtual void sent_piece (peer_request const&);
    │ │ │ │ -virtual void sent_not_interested ();
    │ │ │ │  virtual void sent_have (piece_index_t);
    │ │ │ │ +virtual void sent_not_interested ();
    │ │ │ │  virtual void sent_interested ();
    │ │ │ │ +virtual void sent_unchoke ();
    │ │ │ │  
    │ │ │ │

    called after a choke message has been sent to the peer

    │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    sent_payload()

    │ │ │ │
    │ │ │ │  virtual void sent_payload (int /* bytes */);
    │ │ │ │ @@ -744,16 +744,16 @@
    │ │ │ │  
    │ │ │ │

    this is not called for web seeds

    │ │ │ │ │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    on_piece_pass() on_piece_failed()

    │ │ │ │
    │ │ │ │ -virtual void on_piece_failed (piece_index_t);
    │ │ │ │  virtual void on_piece_pass (piece_index_t);
    │ │ │ │ +virtual void on_piece_failed (piece_index_t);
    │ │ │ │  
    │ │ │ │

    called when a piece that this peer participated in either │ │ │ │ fails or passes the hash_check

    │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    tick()

    │ │ │ │
    │ │ │ │ @@ -773,16 +773,16 @@
    │ │ │ │  
    │ │ │ │
    │ │ │ │

    crypto_plugin

    │ │ │ │

    Declared in "libtorrent/extensions.hpp"

    │ │ │ │
    │ │ │ │  struct crypto_plugin
    │ │ │ │  {
    │ │ │ │ -   virtual void set_outgoing_key (span<char const> key) = 0;
    │ │ │ │     virtual void set_incoming_key (span<char const> key) = 0;
    │ │ │ │ +   virtual void set_outgoing_key (span<char const> key) = 0;
    │ │ │ │     encrypt (span<span<char>> /*send_vec*/) = 0;
    │ │ │ │     virtual std::tuple<int, int, int> decrypt (span<span<char>> /*receive_vec*/) = 0;
    │ │ │ │  };
    │ │ │ │  
    │ │ │ │ [report issue]
    │ │ │ │

    decrypt()

    │ │ │ │
    │ │ │ │ @@ -793,42 +793,42 @@
    │ │ │ │  (consume, produce, packet_size)

    │ │ │ │

    consume is set to the number of bytes which should be trimmed from the │ │ │ │ head of the buffers, default is 0

    │ │ │ │

    produce is set to the number of bytes of payload which are now ready to │ │ │ │ be sent to the upper layer. default is the number of bytes passed in receive_vec

    │ │ │ │

    packet_size is set to the minimum number of bytes which must be read to │ │ │ │ advance the next step of decryption. default is 0

    │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -
    │ │ │ │ -

    create_smart_ban_plugin()

    │ │ │ │ -

    Declared in "libtorrent/extensions/smart_ban.hpp"

    │ │ │ │ -
    │ │ │ │ -std::shared_ptr<torrent_plugin> create_smart_ban_plugin (torrent_handle const&, client_data_t);
    │ │ │ │ -
    │ │ │ │ -

    constructor function for the smart ban extension. The extension keeps │ │ │ │ -track of the data peers have sent us for failing pieces and once the │ │ │ │ -piece completes and passes the hash check bans the peers that turned │ │ │ │ -out to have sent corrupt data. │ │ │ │ -This function can either be passed in the add_torrent_params::extensions │ │ │ │ -field, or via torrent_handle::add_extension().

    │ │ │ │ [report issue]
    │ │ │ │ + │ │ │ │
    │ │ │ │

    create_ut_pex_plugin()

    │ │ │ │

    Declared in "libtorrent/extensions/ut_pex.hpp"

    │ │ │ │
    │ │ │ │  std::shared_ptr<torrent_plugin> create_ut_pex_plugin (torrent_handle const&, client_data_t);
    │ │ │ │  
    │ │ │ │

    constructor function for the ut_pex extension. The ut_pex │ │ │ │ extension allows peers to gossip about their connections, allowing │ │ │ │ the swarm stay well connected and peers aware of more peers in the │ │ │ │ swarm. This extension is enabled by default unless explicitly disabled in │ │ │ │ the session constructor.

    │ │ │ │

    This can either be passed in the add_torrent_params::extensions field, or │ │ │ │ via torrent_handle::add_extension().

    │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    create_smart_ban_plugin()

    │ │ │ │ +

    Declared in "libtorrent/extensions/smart_ban.hpp"

    │ │ │ │ +
    │ │ │ │ +std::shared_ptr<torrent_plugin> create_smart_ban_plugin (torrent_handle const&, client_data_t);
    │ │ │ │ +
    │ │ │ │ +

    constructor function for the smart ban extension. The extension keeps │ │ │ │ +track of the data peers have sent us for failing pieces and once the │ │ │ │ +piece completes and passes the hash check bans the peers that turned │ │ │ │ +out to have sent corrupt data. │ │ │ │ +This function can either be passed in the add_torrent_params::extensions │ │ │ │ +field, or via torrent_handle::add_extension().

    │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    create_ut_metadata_plugin()

    │ │ │ │

    Declared in "libtorrent/extensions/ut_metadata.hpp"

    │ │ │ │
    │ │ │ │  std::shared_ptr<torrent_plugin> create_ut_metadata_plugin (torrent_handle const&, client_data_t);
    │ │ │ │  
    │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -19,42 +19,42 @@ │ │ │ │ │ o _o_n___t_i_c_k_(_) │ │ │ │ │ o _g_e_t___u_n_c_h_o_k_e___p_r_i_o_r_i_t_y_(_) │ │ │ │ │ o _l_o_a_d___s_t_a_t_e_(_) │ │ │ │ │ * _t_o_r_r_e_n_t___p_l_u_g_i_n │ │ │ │ │ o _n_e_w___c_o_n_n_e_c_t_i_o_n_(_) │ │ │ │ │ o _o_n___p_i_e_c_e___p_a_s_s_(_)_ _o_n___p_i_e_c_e___f_a_i_l_e_d_(_) │ │ │ │ │ o _t_i_c_k_(_) │ │ │ │ │ - o _o_n___r_e_s_u_m_e_(_)_ _o_n___p_a_u_s_e_(_) │ │ │ │ │ + o _o_n___p_a_u_s_e_(_)_ _o_n___r_e_s_u_m_e_(_) │ │ │ │ │ o _o_n___f_i_l_e_s___c_h_e_c_k_e_d_(_) │ │ │ │ │ o _o_n___s_t_a_t_e_(_) │ │ │ │ │ o _o_n___a_d_d___p_e_e_r_(_) │ │ │ │ │ * _p_e_e_r___p_l_u_g_i_n │ │ │ │ │ o _t_y_p_e_(_) │ │ │ │ │ o _a_d_d___h_a_n_d_s_h_a_k_e_(_) │ │ │ │ │ o _o_n___d_i_s_c_o_n_n_e_c_t_(_) │ │ │ │ │ o _o_n___c_o_n_n_e_c_t_e_d_(_) │ │ │ │ │ o _o_n___h_a_n_d_s_h_a_k_e_(_) │ │ │ │ │ o _o_n___e_x_t_e_n_s_i_o_n___h_a_n_d_s_h_a_k_e_(_) │ │ │ │ │ - o _o_n___r_e_q_u_e_s_t_(_)_ _o_n___c_h_o_k_e_(_)_ _o_n___h_a_v_e___n_o_n_e_(_)_ _o_n___i_n_t_e_r_e_s_t_e_d_(_)_ _o_n___u_n_c_h_o_k_e_(_) │ │ │ │ │ - _o_n___b_i_t_f_i_e_l_d_(_)_ _o_n___a_l_l_o_w_e_d___f_a_s_t_(_)_ _o_n___h_a_v_e_(_)_ _o_n___h_a_v_e___a_l_l_(_) │ │ │ │ │ - _o_n___d_o_n_t___h_a_v_e_(_)_ _o_n___n_o_t___i_n_t_e_r_e_s_t_e_d_(_) │ │ │ │ │ + o _o_n___h_a_v_e_(_)_ _o_n___u_n_c_h_o_k_e_(_)_ _o_n___c_h_o_k_e_(_)_ _o_n___r_e_q_u_e_s_t_(_)_ _o_n___n_o_t___i_n_t_e_r_e_s_t_e_d_(_) │ │ │ │ │ + _o_n___h_a_v_e___n_o_n_e_(_)_ _o_n___a_l_l_o_w_e_d___f_a_s_t_(_)_ _o_n___b_i_t_f_i_e_l_d_(_)_ _o_n___i_n_t_e_r_e_s_t_e_d_(_) │ │ │ │ │ + _o_n___h_a_v_e___a_l_l_(_)_ _o_n___d_o_n_t___h_a_v_e_(_) │ │ │ │ │ o _o_n___p_i_e_c_e_(_) │ │ │ │ │ - o _s_e_n_t___i_n_t_e_r_e_s_t_e_d_(_)_ _s_e_n_t___n_o_t___i_n_t_e_r_e_s_t_e_d_(_)_ _s_e_n_t___p_i_e_c_e_(_)_ _s_e_n_t___u_n_c_h_o_k_e_(_) │ │ │ │ │ - _s_e_n_t___h_a_v_e_(_) │ │ │ │ │ + o _s_e_n_t___n_o_t___i_n_t_e_r_e_s_t_e_d_(_)_ _s_e_n_t___h_a_v_e_(_)_ _s_e_n_t___i_n_t_e_r_e_s_t_e_d_(_)_ _s_e_n_t___u_n_c_h_o_k_e_(_) │ │ │ │ │ + _s_e_n_t___p_i_e_c_e_(_) │ │ │ │ │ o _s_e_n_t___p_a_y_l_o_a_d_(_) │ │ │ │ │ o _c_a_n___d_i_s_c_o_n_n_e_c_t_(_) │ │ │ │ │ o _o_n___e_x_t_e_n_d_e_d_(_) │ │ │ │ │ o _o_n___u_n_k_n_o_w_n___m_e_s_s_a_g_e_(_) │ │ │ │ │ o _o_n___p_i_e_c_e___p_a_s_s_(_)_ _o_n___p_i_e_c_e___f_a_i_l_e_d_(_) │ │ │ │ │ o _t_i_c_k_(_) │ │ │ │ │ o _w_r_i_t_e___r_e_q_u_e_s_t_(_) │ │ │ │ │ * _c_r_y_p_t_o___p_l_u_g_i_n │ │ │ │ │ o _d_e_c_r_y_p_t_(_) │ │ │ │ │ - * _c_r_e_a_t_e___s_m_a_r_t___b_a_n___p_l_u_g_i_n_(_) │ │ │ │ │ * _c_r_e_a_t_e___u_t___p_e_x___p_l_u_g_i_n_(_) │ │ │ │ │ + * _c_r_e_a_t_e___s_m_a_r_t___b_a_n___p_l_u_g_i_n_(_) │ │ │ │ │ * _c_r_e_a_t_e___u_t___m_e_t_a_d_a_t_a___p_l_u_g_i_n_(_) │ │ │ │ │ libtorrent has a _p_l_u_g_i_n interface for implementing extensions to the protocol. │ │ │ │ │ These can be general extensions for transferring metadata or peer exchange │ │ │ │ │ extensions, or it could be used to provide a way to customize the protocol to │ │ │ │ │ fit a particular (closed) network. │ │ │ │ │ In short, the _p_l_u_g_i_n interface makes it possible to: │ │ │ │ │ * register extension messages (sent in the extension handshake), see │ │ │ │ │ @@ -140,67 +140,67 @@ │ │ │ │ │ the _p_e_e_r___c_o_n_n_e_c_t_i_o_n___h_a_n_d_l_e class provides a handle to the internal peer │ │ │ │ │ connection object, to be used by plugins. This is a low level interface that │ │ │ │ │ may not be stable across libtorrent versions │ │ │ │ │ struct peer_connection_handle │ │ │ │ │ { │ │ │ │ │ explicit ppeeeerr__ccoonnnneeccttiioonn__hhaannddllee (std::weak_ptr impl); │ │ │ │ │ connection_type ttyyppee () const; │ │ │ │ │ - void aadddd__eexxtteennssiioonn (std::shared_ptr); │ │ │ │ │ peer_plugin const* ffiinndd__pplluuggiinn (string_view type) const; │ │ │ │ │ + void aadddd__eexxtteennssiioonn (std::shared_ptr); │ │ │ │ │ bool iiss__sseeeedd () const; │ │ │ │ │ bool uuppllooaadd__oonnllyy () const; │ │ │ │ │ bool hhaass__ppiieeccee (piece_index_t i) const; │ │ │ │ │ peer_id const& ppiidd () const; │ │ │ │ │ - bool iiss__iinntteerreessttiinngg () const; │ │ │ │ │ bool iiss__cchhookkeedd () const; │ │ │ │ │ - bool iiss__ppeeeerr__iinntteerreesstteedd () const; │ │ │ │ │ + bool iiss__iinntteerreessttiinngg () const; │ │ │ │ │ bool hhaass__ppeeeerr__cchhookkeedd () const; │ │ │ │ │ + bool iiss__ppeeeerr__iinntteerreesstteedd () const; │ │ │ │ │ void mmaayybbee__uunncchhookkee__tthhiiss__ppeeeerr (); │ │ │ │ │ void cchhookkee__tthhiiss__ppeeeerr (); │ │ │ │ │ void ggeett__ppeeeerr__iinnffoo (peer_info& p) const; │ │ │ │ │ torrent_handle aassssoocciiaatteedd__ttoorrrreenntt () const; │ │ │ │ │ - _t_c_p_:_:_e_n_d_p_o_i_n_t llooccaall__eennddppooiinntt () const; │ │ │ │ │ _t_c_p_:_:_e_n_d_p_o_i_n_t const& rreemmoottee () const; │ │ │ │ │ + _t_c_p_:_:_e_n_d_p_o_i_n_t llooccaall__eennddppooiinntt () const; │ │ │ │ │ + bool iiss__ccoonnnneeccttiinngg () const; │ │ │ │ │ + bool iiss__ddiissccoonnnneeccttiinngg () const; │ │ │ │ │ void ddiissccoonnnneecctt (error_code const& ec, operation_t op │ │ │ │ │ , disconnect_severity_t = peer_connection_interface::normal); │ │ │ │ │ - bool iiss__ccoonnnneeccttiinngg () const; │ │ │ │ │ bool iiss__oouuttggooiinngg () const; │ │ │ │ │ - bool iiss__ddiissccoonnnneeccttiinngg () const; │ │ │ │ │ - bool oonn__llooccaall__nneettwwoorrkk () const; │ │ │ │ │ bool iiggnnoorree__uunncchhookkee__sslloottss () const; │ │ │ │ │ + bool oonn__llooccaall__nneettwwoorrkk () const; │ │ │ │ │ bool ffaaiilleedd () const; │ │ │ │ │ - bool sshhoouulldd__lloogg (peer_log_alert::direction_t direction) const; │ │ │ │ │ void ppeeeerr__lloogg (peer_log_alert::direction_t direction │ │ │ │ │ , char const* event, char const* fmt = "", ...) const TORRENT_FORMAT │ │ │ │ │ (4,5); │ │ │ │ │ + bool sshhoouulldd__lloogg (peer_log_alert::direction_t direction) const; │ │ │ │ │ bool ccaann__ddiissccoonnnneecctt (error_code const& ec) const; │ │ │ │ │ bool hhaass__mmeettaaddaattaa () const; │ │ │ │ │ bool iinn__hhaannddsshhaakkee () const; │ │ │ │ │ void sseenndd__bbuuffffeerr (char const* begin, int size); │ │ │ │ │ - time_point ttiimmee__ooff__llaasstt__uunncchhookkee () const; │ │ │ │ │ std::time_t llaasstt__sseeeenn__ccoommpplleettee () const; │ │ │ │ │ + time_point ttiimmee__ooff__llaasstt__uunncchhookkee () const; │ │ │ │ │ bool ooppeerraattoorr==== (peer_connection_handle const& o) const; │ │ │ │ │ - bool ooppeerraattoorr!!== (peer_connection_handle const& o) const; │ │ │ │ │ bool ooppeerraattoorr<< (peer_connection_handle const& o) const; │ │ │ │ │ + bool ooppeerraattoorr!!== (peer_connection_handle const& o) const; │ │ │ │ │ std::shared_ptr nnaattiivvee__hhaannddllee () const; │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ bbtt__ppeeeerr__ccoonnnneeccttiioonn__hhaannddllee ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n___h_a_n_d_l_e_._h_p_p" │ │ │ │ │ The _b_t___p_e_e_r___c_o_n_n_e_c_t_i_o_n___h_a_n_d_l_e provides a handle to the internal bittorrent peer │ │ │ │ │ connection object to plugins. It's low level and may not be a stable API across │ │ │ │ │ libtorrent versions. │ │ │ │ │ struct bt_peer_connection_handle : peer_connection_handle │ │ │ │ │ { │ │ │ │ │ explicit bbtt__ppeeeerr__ccoonnnneeccttiioonn__hhaannddllee (peer_connection_handle pc); │ │ │ │ │ bool ppaacckkeett__ffiinniisshheedd () const; │ │ │ │ │ bool ssuuppppoorrtt__eexxtteennssiioonnss () const; │ │ │ │ │ bool ssuuppppoorrttss__eennccrryyppttiioonn () const; │ │ │ │ │ - void sswwiittcchh__sseenndd__ccrryyppttoo (std::shared_ptr crypto); │ │ │ │ │ void sswwiittcchh__rreeccvv__ccrryyppttoo (std::shared_ptr crypto); │ │ │ │ │ + void sswwiittcchh__sseenndd__ccrryyppttoo (std::shared_ptr crypto); │ │ │ │ │ std::shared_ptr nnaattiivvee__hhaannddllee () const; │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ pplluuggiinn ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_e_x_t_e_n_s_i_o_n_s_._h_p_p" │ │ │ │ │ this is the base class for a _s_e_s_s_i_o_n _p_l_u_g_i_n. One primary feature is that it is │ │ │ │ │ notified of all torrents that are added to the _s_e_s_s_i_o_n, and can add its own │ │ │ │ │ @@ -321,19 +321,19 @@ │ │ │ │ │ Torrent plugins are associated with a single torrent and have a number of │ │ │ │ │ functions called at certain events. Many of its functions have the ability to │ │ │ │ │ change or override the default libtorrent behavior. │ │ │ │ │ struct torrent_plugin │ │ │ │ │ { │ │ │ │ │ virtual std::shared_ptr nneeww__ccoonnnneeccttiioonn (peer_connection_handle │ │ │ │ │ const&); │ │ │ │ │ - virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ virtual void oonn__ppiieeccee__ppaassss (piece_index_t); │ │ │ │ │ + virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ virtual void ttiicckk (); │ │ │ │ │ - virtual bool oonn__rreessuummee (); │ │ │ │ │ virtual bool oonn__ppaauussee (); │ │ │ │ │ + virtual bool oonn__rreessuummee (); │ │ │ │ │ virtual void oonn__ffiilleess__cchheecckkeedd (); │ │ │ │ │ virtual void oonn__ssttaattee (torrent_status::state_t); │ │ │ │ │ virtual void oonn__aadddd__ppeeeerr (tcp::endpoint const&, │ │ │ │ │ peer_source_flags_t, add_peer_flags_t); │ │ │ │ │ │ │ │ │ │ static constexpr add_peer_flags_t ffiirrsstt__ttiimmee = 1_bit; │ │ │ │ │ static constexpr add_peer_flags_t ffiilltteerreedd = 2_bit; │ │ │ │ │ @@ -351,29 +351,29 @@ │ │ │ │ │ The peer_connection_handle will be valid as long as the shared_ptr is being │ │ │ │ │ held by the torrent object. So, it is generally a good idea to not keep a │ │ │ │ │ shared_ptr to your own _p_e_e_r___p_l_u_g_i_n. If you want to keep references to it, use │ │ │ │ │ weak_ptr. │ │ │ │ │ If this function throws an exception, the connection will be closed. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** oonn__ppiieeccee__ppaassss(()) oonn__ppiieeccee__ffaaiilleedd(()) ********** │ │ │ │ │ -virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ virtual void oonn__ppiieeccee__ppaassss (piece_index_t); │ │ │ │ │ +virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ These hooks are called when a piece passes the hash check or fails the hash │ │ │ │ │ check, respectively. The index is the piece index that was downloaded. It is │ │ │ │ │ possible to access the list of peers that participated in sending the piece │ │ │ │ │ through the torrent and the piece_picker. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** ttiicckk(()) ********** │ │ │ │ │ virtual void ttiicckk (); │ │ │ │ │ This hook is called approximately once per second. It is a way of making it │ │ │ │ │ easy for plugins to do timed events, for sending messages or whatever. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** oonn__rreessuummee(()) oonn__ppaauussee(()) ********** │ │ │ │ │ -virtual bool oonn__rreessuummee (); │ │ │ │ │ +********** oonn__ppaauussee(()) oonn__rreessuummee(()) ********** │ │ │ │ │ virtual bool oonn__ppaauussee (); │ │ │ │ │ +virtual bool oonn__rreessuummee (); │ │ │ │ │ These hooks are called when the torrent is paused and resumed respectively. The │ │ │ │ │ return value indicates if the event was handled. A return value of true │ │ │ │ │ indicates that it was handled, and no other _p_l_u_g_i_n after this one will have │ │ │ │ │ this hook function called, and the standard handler will also not be invoked. │ │ │ │ │ So, returning true effectively overrides the standard behavior of pause or │ │ │ │ │ resume. │ │ │ │ │ Note that if you call pause() or resume() on the torrent from your handler it │ │ │ │ │ @@ -419,51 +419,51 @@ │ │ │ │ │ { │ │ │ │ │ virtual string_view ttyyppee () const; │ │ │ │ │ virtual void aadddd__hhaannddsshhaakkee (entry&); │ │ │ │ │ virtual void oonn__ddiissccoonnnneecctt (error_code const&); │ │ │ │ │ virtual void oonn__ccoonnnneecctteedd (); │ │ │ │ │ virtual bool oonn__hhaannddsshhaakkee (span); │ │ │ │ │ virtual bool oonn__eexxtteennssiioonn__hhaannddsshhaakkee (bdecode_node const&); │ │ │ │ │ - virtual bool oonn__hhaavvee__nnoonnee (); │ │ │ │ │ - virtual bool oonn__nnoott__iinntteerreesstteedd (); │ │ │ │ │ - virtual bool oonn__aalllloowweedd__ffaasstt (piece_index_t); │ │ │ │ │ - virtual bool oonn__rreeqquueesstt (peer_request const&); │ │ │ │ │ virtual bool oonn__bbiittffiieelldd (bitfield const& //**bbiittffiieelldd**//); │ │ │ │ │ - virtual bool oonn__ddoonntt__hhaavvee (piece_index_t); │ │ │ │ │ + virtual bool oonn__nnoott__iinntteerreesstteedd (); │ │ │ │ │ + virtual bool oonn__hhaavvee__nnoonnee (); │ │ │ │ │ virtual bool oonn__cchhookkee (); │ │ │ │ │ virtual bool oonn__hhaavvee__aallll (); │ │ │ │ │ - virtual bool oonn__uunncchhookkee (); │ │ │ │ │ + virtual bool oonn__aalllloowweedd__ffaasstt (piece_index_t); │ │ │ │ │ virtual bool oonn__iinntteerreesstteedd (); │ │ │ │ │ + virtual bool oonn__ddoonntt__hhaavvee (piece_index_t); │ │ │ │ │ virtual bool oonn__hhaavvee (piece_index_t); │ │ │ │ │ + virtual bool oonn__uunncchhookkee (); │ │ │ │ │ + virtual bool oonn__rreeqquueesstt (peer_request const&); │ │ │ │ │ virtual bool oonn__ppiieeccee (peer_request const& //**ppiieeccee**// │ │ │ │ │ , span //**bbuuff**//); │ │ │ │ │ - virtual bool oonn__rreejjeecctt (peer_request const&); │ │ │ │ │ - virtual bool oonn__ccaanncceell (peer_request const&); │ │ │ │ │ virtual bool oonn__ssuuggggeesstt (piece_index_t); │ │ │ │ │ - virtual void sseenntt__rreeqquueesstt (peer_request const&); │ │ │ │ │ - virtual void sseenntt__aallllooww__ffaasstt (piece_index_t); │ │ │ │ │ - virtual void sseenntt__ssuuggggeesstt (piece_index_t); │ │ │ │ │ - virtual void sseenntt__ccaanncceell (peer_request const&); │ │ │ │ │ - virtual void sseenntt__cchhookkee (); │ │ │ │ │ + virtual bool oonn__ccaanncceell (peer_request const&); │ │ │ │ │ + virtual bool oonn__rreejjeecctt (peer_request const&); │ │ │ │ │ virtual void sseenntt__rreejjeecctt__rreeqquueesstt (peer_request const&); │ │ │ │ │ + virtual void sseenntt__cchhookkee (); │ │ │ │ │ + virtual void sseenntt__ccaanncceell (peer_request const&); │ │ │ │ │ + virtual void sseenntt__aallllooww__ffaasstt (piece_index_t); │ │ │ │ │ virtual void sseenntt__hhaavvee__nnoonnee (); │ │ │ │ │ virtual void sseenntt__hhaavvee__aallll (); │ │ │ │ │ - virtual void sseenntt__uunncchhookkee (); │ │ │ │ │ + virtual void sseenntt__ssuuggggeesstt (piece_index_t); │ │ │ │ │ + virtual void sseenntt__rreeqquueesstt (peer_request const&); │ │ │ │ │ virtual void sseenntt__ppiieeccee (peer_request const&); │ │ │ │ │ - virtual void sseenntt__nnoott__iinntteerreesstteedd (); │ │ │ │ │ virtual void sseenntt__hhaavvee (piece_index_t); │ │ │ │ │ + virtual void sseenntt__nnoott__iinntteerreesstteedd (); │ │ │ │ │ virtual void sseenntt__iinntteerreesstteedd (); │ │ │ │ │ + virtual void sseenntt__uunncchhookkee (); │ │ │ │ │ virtual void sseenntt__ppaayyllooaadd (int //** bbyytteess **//); │ │ │ │ │ virtual bool ccaann__ddiissccoonnnneecctt (error_code const& //**eecc**//); │ │ │ │ │ virtual bool oonn__eexxtteennddeedd (int //**lleennggtthh**//, int //**mmssgg**//, │ │ │ │ │ span //**bbooddyy**//); │ │ │ │ │ virtual bool oonn__uunnkknnoowwnn__mmeessssaaggee (int //**lleennggtthh**//, int //**mmssgg**//, │ │ │ │ │ span //**bbooddyy**//); │ │ │ │ │ - virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ virtual void oonn__ppiieeccee__ppaassss (piece_index_t); │ │ │ │ │ + virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ virtual void ttiicckk (); │ │ │ │ │ virtual bool wwrriittee__rreeqquueesstt (peer_request const&); │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** ttyyppee(()) ********** │ │ │ │ │ virtual string_view ttyyppee () const; │ │ │ │ │ This function is expected to return the name of the _p_l_u_g_i_n. │ │ │ │ │ @@ -491,48 +491,48 @@ │ │ │ │ │ ********** oonn__eexxtteennssiioonn__hhaannddsshhaakkee(()) ********** │ │ │ │ │ virtual bool oonn__eexxtteennssiioonn__hhaannddsshhaakkee (bdecode_node const&); │ │ │ │ │ called when the extension handshake from the other end is received if this │ │ │ │ │ returns false, it means that this extension isn't supported by this peer. It │ │ │ │ │ will result in this _p_e_e_r___p_l_u_g_i_n being removed from the peer_connection and │ │ │ │ │ destructed. this is not called for web seeds │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** oonn__rreeqquueesstt(()) oonn__cchhookkee(()) oonn__hhaavvee__nnoonnee(()) oonn__iinntteerreesstteedd(()) oonn__uunncchhookkee(()) │ │ │ │ │ -oonn__bbiittffiieelldd(()) oonn__aalllloowweedd__ffaasstt(()) oonn__hhaavvee(()) oonn__hhaavvee__aallll(()) oonn__ddoonntt__hhaavvee(()) │ │ │ │ │ -oonn__nnoott__iinntteerreesstteedd(()) ********** │ │ │ │ │ -virtual bool oonn__hhaavvee__nnoonnee (); │ │ │ │ │ -virtual bool oonn__nnoott__iinntteerreesstteedd (); │ │ │ │ │ -virtual bool oonn__aalllloowweedd__ffaasstt (piece_index_t); │ │ │ │ │ -virtual bool oonn__rreeqquueesstt (peer_request const&); │ │ │ │ │ +********** oonn__hhaavvee(()) oonn__uunncchhookkee(()) oonn__cchhookkee(()) oonn__rreeqquueesstt(()) oonn__nnoott__iinntteerreesstteedd(()) │ │ │ │ │ +oonn__hhaavvee__nnoonnee(()) oonn__aalllloowweedd__ffaasstt(()) oonn__bbiittffiieelldd(()) oonn__iinntteerreesstteedd(()) oonn__hhaavvee__aallll(()) │ │ │ │ │ +oonn__ddoonntt__hhaavvee(()) ********** │ │ │ │ │ virtual bool oonn__bbiittffiieelldd (bitfield const& //**bbiittffiieelldd**//); │ │ │ │ │ -virtual bool oonn__ddoonntt__hhaavvee (piece_index_t); │ │ │ │ │ +virtual bool oonn__nnoott__iinntteerreesstteedd (); │ │ │ │ │ +virtual bool oonn__hhaavvee__nnoonnee (); │ │ │ │ │ virtual bool oonn__cchhookkee (); │ │ │ │ │ virtual bool oonn__hhaavvee__aallll (); │ │ │ │ │ -virtual bool oonn__uunncchhookkee (); │ │ │ │ │ +virtual bool oonn__aalllloowweedd__ffaasstt (piece_index_t); │ │ │ │ │ virtual bool oonn__iinntteerreesstteedd (); │ │ │ │ │ +virtual bool oonn__ddoonntt__hhaavvee (piece_index_t); │ │ │ │ │ virtual bool oonn__hhaavvee (piece_index_t); │ │ │ │ │ +virtual bool oonn__uunncchhookkee (); │ │ │ │ │ +virtual bool oonn__rreeqquueesstt (peer_request const&); │ │ │ │ │ returning true from any of the message handlers indicates that the _p_l_u_g_i_n has │ │ │ │ │ handled the message. it will break the _p_l_u_g_i_n chain traversing and not let │ │ │ │ │ anyone else handle the message, including the default handler. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** oonn__ppiieeccee(()) ********** │ │ │ │ │ virtual bool oonn__ppiieeccee (peer_request const& //**ppiieeccee**// │ │ │ │ │ , span //**bbuuff**//); │ │ │ │ │ This function is called when the peer connection is receiving a piece. buf │ │ │ │ │ points (non-owning pointer) to the data in an internal immutable disk buffer. │ │ │ │ │ The length of the data is specified in the length member of the piece │ │ │ │ │ parameter. returns true to indicate that the piece is handled and the rest of │ │ │ │ │ the logic should be ignored. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** sseenntt__iinntteerreesstteedd(()) sseenntt__nnoott__iinntteerreesstteedd(()) sseenntt__ppiieeccee(()) sseenntt__uunncchhookkee(()) │ │ │ │ │ -sseenntt__hhaavvee(()) ********** │ │ │ │ │ -virtual void sseenntt__uunncchhookkee (); │ │ │ │ │ +********** sseenntt__nnoott__iinntteerreesstteedd(()) sseenntt__hhaavvee(()) sseenntt__iinntteerreesstteedd(()) sseenntt__uunncchhookkee(()) │ │ │ │ │ +sseenntt__ppiieeccee(()) ********** │ │ │ │ │ virtual void sseenntt__ppiieeccee (peer_request const&); │ │ │ │ │ -virtual void sseenntt__nnoott__iinntteerreesstteedd (); │ │ │ │ │ virtual void sseenntt__hhaavvee (piece_index_t); │ │ │ │ │ +virtual void sseenntt__nnoott__iinntteerreesstteedd (); │ │ │ │ │ virtual void sseenntt__iinntteerreesstteedd (); │ │ │ │ │ +virtual void sseenntt__uunncchhookkee (); │ │ │ │ │ called after a choke message has been sent to the peer │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** sseenntt__ppaayyllooaadd(()) ********** │ │ │ │ │ virtual void sseenntt__ppaayyllooaadd (int //** bbyytteess **//); │ │ │ │ │ called after piece data has been sent to the peer this can be used for stats │ │ │ │ │ book keeping │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ @@ -556,16 +556,16 @@ │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** oonn__uunnkknnoowwnn__mmeessssaaggee(()) ********** │ │ │ │ │ virtual bool oonn__uunnkknnoowwnn__mmeessssaaggee (int //**lleennggtthh**//, int //**mmssgg**//, │ │ │ │ │ span //**bbooddyy**//); │ │ │ │ │ this is not called for web seeds │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** oonn__ppiieeccee__ppaassss(()) oonn__ppiieeccee__ffaaiilleedd(()) ********** │ │ │ │ │ -virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ virtual void oonn__ppiieeccee__ppaassss (piece_index_t); │ │ │ │ │ +virtual void oonn__ppiieeccee__ffaaiilleedd (piece_index_t); │ │ │ │ │ called when a piece that this peer participated in either fails or passes the │ │ │ │ │ hash_check │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** ttiicckk(()) ********** │ │ │ │ │ virtual void ttiicckk (); │ │ │ │ │ called approximately once every second │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ @@ -575,16 +575,16 @@ │ │ │ │ │ original request message won't be sent and no other _p_l_u_g_i_n will have this │ │ │ │ │ function called. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ ccrryyppttoo__pplluuggiinn ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_e_x_t_e_n_s_i_o_n_s_._h_p_p" │ │ │ │ │ struct crypto_plugin │ │ │ │ │ { │ │ │ │ │ - virtual void sseett__oouuttggooiinngg__kkeeyy (span key) = 0; │ │ │ │ │ virtual void sseett__iinnccoommiinngg__kkeeyy (span key) = 0; │ │ │ │ │ + virtual void sseett__oouuttggooiinngg__kkeeyy (span key) = 0; │ │ │ │ │ eennccrryypptt (span> //**sseenndd__vveecc**//) = 0; │ │ │ │ │ virtual std::tuple ddeeccrryypptt (span> //**rreecceeiivvee__vveecc**// │ │ │ │ │ ) = 0; │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** ddeeccrryypptt(()) ********** │ │ │ │ │ virtual std::tuple ddeeccrryypptt (span> //**rreecceeiivvee__vveecc**//) = │ │ │ │ │ @@ -594,35 +594,35 @@ │ │ │ │ │ consume is set to the number of bytes which should be trimmed from the head of │ │ │ │ │ the buffers, default is 0 │ │ │ │ │ produce is set to the number of bytes of payload which are now ready to be sent │ │ │ │ │ to the upper layer. default is the number of bytes passed in receive_vec │ │ │ │ │ packet_size is set to the minimum number of bytes which must be read to advance │ │ │ │ │ the next step of decryption. default is 0 │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -************ ccrreeaattee__ssmmaarrtt__bbaann__pplluuggiinn(()) ************ │ │ │ │ │ -Declared in "_l_i_b_t_o_r_r_e_n_t_/_e_x_t_e_n_s_i_o_n_s_/_s_m_a_r_t___b_a_n_._h_p_p" │ │ │ │ │ -std::shared_ptr ccrreeaattee__ssmmaarrtt__bbaann__pplluuggiinn (torrent_handle const&, │ │ │ │ │ -client_data_t); │ │ │ │ │ -constructor function for the smart ban extension. The extension keeps track of │ │ │ │ │ -the data peers have sent us for failing pieces and once the piece completes and │ │ │ │ │ -passes the hash check bans the peers that turned out to have sent corrupt data. │ │ │ │ │ -This function can either be passed in the add_torrent_params::extensions field, │ │ │ │ │ -or via _t_o_r_r_e_n_t___h_a_n_d_l_e_:_:_a_d_d___e_x_t_e_n_s_i_o_n_(_). │ │ │ │ │ -[_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ ccrreeaattee__uutt__ppeexx__pplluuggiinn(()) ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_e_x_t_e_n_s_i_o_n_s_/_u_t___p_e_x_._h_p_p" │ │ │ │ │ std::shared_ptr ccrreeaattee__uutt__ppeexx__pplluuggiinn (torrent_handle const&, │ │ │ │ │ client_data_t); │ │ │ │ │ constructor function for the ut_pex extension. The ut_pex extension allows │ │ │ │ │ peers to gossip about their connections, allowing the swarm stay well connected │ │ │ │ │ and peers aware of more peers in the swarm. This extension is enabled by │ │ │ │ │ default unless explicitly disabled in the _s_e_s_s_i_o_n constructor. │ │ │ │ │ This can either be passed in the add_torrent_params::extensions field, or via │ │ │ │ │ _t_o_r_r_e_n_t___h_a_n_d_l_e_:_:_a_d_d___e_x_t_e_n_s_i_o_n_(_). │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ +************ ccrreeaattee__ssmmaarrtt__bbaann__pplluuggiinn(()) ************ │ │ │ │ │ +Declared in "_l_i_b_t_o_r_r_e_n_t_/_e_x_t_e_n_s_i_o_n_s_/_s_m_a_r_t___b_a_n_._h_p_p" │ │ │ │ │ +std::shared_ptr ccrreeaattee__ssmmaarrtt__bbaann__pplluuggiinn (torrent_handle const&, │ │ │ │ │ +client_data_t); │ │ │ │ │ +constructor function for the smart ban extension. The extension keeps track of │ │ │ │ │ +the data peers have sent us for failing pieces and once the piece completes and │ │ │ │ │ +passes the hash check bans the peers that turned out to have sent corrupt data. │ │ │ │ │ +This function can either be passed in the add_torrent_params::extensions field, │ │ │ │ │ +or via _t_o_r_r_e_n_t___h_a_n_d_l_e_:_:_a_d_d___e_x_t_e_n_s_i_o_n_(_). │ │ │ │ │ +[_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ ccrreeaattee__uutt__mmeettaaddaattaa__pplluuggiinn(()) ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_e_x_t_e_n_s_i_o_n_s_/_u_t___m_e_t_a_d_a_t_a_._h_p_p" │ │ │ │ │ std::shared_ptr ccrreeaattee__uutt__mmeettaaddaattaa__pplluuggiinn (torrent_handle │ │ │ │ │ const&, client_data_t); │ │ │ │ │ constructor function for the ut_metadata extension. The ut_metadata extension │ │ │ │ │ allows peers to request the .torrent file (or more specifically the info- │ │ │ │ │ dictionary of the .torrent file) from each other. This is the main building │ │ │ ├── ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Resume_Data.html │ │ │ │ @@ -29,31 +29,31 @@ │ │ │ │ │ │ │ │ │ │ │ │

    home

    │ │ │ │
    │ │ │ │

    Table of contents

    │ │ │ │ │ │ │ │
    │ │ │ │ [report issue]
    │ │ │ │

    read_resume_data()

    │ │ │ │

    Declared in "libtorrent/read_resume_data.hpp"

    │ │ │ │
    │ │ │ │ -add_torrent_params read_resume_data (span<char const> buffer
    │ │ │ │ -   , load_torrent_limits const& cfg = {});
    │ │ │ │  add_torrent_params read_resume_data (bdecode_node const& rd
    │ │ │ │     , int piece_limit = 0x200000);
    │ │ │ │ -add_torrent_params read_resume_data (bdecode_node const& rd
    │ │ │ │ -   , error_code& ec, int piece_limit = 0x200000);
    │ │ │ │ +add_torrent_params read_resume_data (span<char const> buffer
    │ │ │ │ +   , load_torrent_limits const& cfg = {});
    │ │ │ │  add_torrent_params read_resume_data (span<char const> buffer
    │ │ │ │     , error_code& ec, load_torrent_limits const& cfg = {});
    │ │ │ │ +add_torrent_params read_resume_data (bdecode_node const& rd
    │ │ │ │ +   , error_code& ec, int piece_limit = 0x200000);
    │ │ │ │  
    │ │ │ │

    these functions are used to parse resume data and populate the appropriate │ │ │ │ fields in an add_torrent_params object. This object can then be used to add │ │ │ │ the actual torrent_info object to and pass to session::add_torrent() or │ │ │ │ session::async_add_torrent().

    │ │ │ │

    If the client wants to override any field that was loaded from the resume │ │ │ │ data, e.g. save_path, those fields must be changed after loading resume │ │ │ │ @@ -61,35 +61,35 @@ │ │ │ │

    The piece_limit parameter determines the largest number of pieces │ │ │ │ allowed in the torrent that may be loaded as part of the resume data, if │ │ │ │ it contains an info field. The overloads that take a flat buffer are │ │ │ │ instead configured with limits on torrent sizes via load_torrent limits.

    │ │ │ │

    In order to support large torrents, it may also be necessary to raise the │ │ │ │ settings_pack::max_piece_count setting and pass a higher limit to calls │ │ │ │ to torrent_info::parse_info_section().

    │ │ │ │ - │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    write_resume_data_buf() write_resume_data()

    │ │ │ │ + │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    write_resume_data() write_resume_data_buf()

    │ │ │ │

    Declared in "libtorrent/write_resume_data.hpp"

    │ │ │ │
    │ │ │ │ -entry write_resume_data (add_torrent_params const& atp);
    │ │ │ │  std::vector<char> write_resume_data_buf (add_torrent_params const& atp);
    │ │ │ │ +entry write_resume_data (add_torrent_params const& atp);
    │ │ │ │  
    │ │ │ │

    this function turns the resume data in an add_torrent_params object │ │ │ │ into a bencoded structure

    │ │ │ │ │ │ │ │ [report issue]
    │ │ │ │
    │ │ │ │

    write_torrent_file() write_torrent_file_buf()

    │ │ │ │

    Declared in "libtorrent/write_resume_data.hpp"

    │ │ │ │
    │ │ │ │  entry write_torrent_file (add_torrent_params const& atp);
    │ │ │ │ +entry write_torrent_file (add_torrent_params const& atp, write_torrent_flags_t flags);
    │ │ │ │  std::vector<char> write_torrent_file_buf (add_torrent_params const& atp
    │ │ │ │     , write_torrent_flags_t flags);
    │ │ │ │ -entry write_torrent_file (add_torrent_params const& atp, write_torrent_flags_t flags);
    │ │ │ │  
    │ │ │ │

    writes only the fields to create a .torrent file. This function may fail │ │ │ │ with a std::system_error exception if:

    │ │ │ │
      │ │ │ │
    • The add_torrent_params object passed to this function does not contain the │ │ │ │ info dictionary (the ti field)
    • │ │ │ │
    • The piece layers are not complete for all files that need them
    • │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -1,27 +1,27 @@ │ │ │ │ │ > │ │ │ │ │ _[_l_i_b_t_o_r_r_e_n_t_ _l_o_g_o_] │ │ │ │ │ VVeerrssiioonn:: 2.0.11 │ │ │ │ │ _h_o_m_e │ │ │ │ │ Table of contents │ │ │ │ │ * _r_e_a_d___r_e_s_u_m_e___d_a_t_a_(_) │ │ │ │ │ - * _w_r_i_t_e___r_e_s_u_m_e___d_a_t_a___b_u_f_(_)_ _w_r_i_t_e___r_e_s_u_m_e___d_a_t_a_(_) │ │ │ │ │ + * _w_r_i_t_e___r_e_s_u_m_e___d_a_t_a_(_)_ _w_r_i_t_e___r_e_s_u_m_e___d_a_t_a___b_u_f_(_) │ │ │ │ │ * _w_r_i_t_e___t_o_r_r_e_n_t___f_i_l_e_(_)_ _w_r_i_t_e___t_o_r_r_e_n_t___f_i_l_e___b_u_f_(_) │ │ │ │ │ * _w_r_i_t_e___t_o_r_r_e_n_t___f_l_a_g_s___t │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ rreeaadd__rreessuummee__ddaattaa(()) ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_r_e_a_d___r_e_s_u_m_e___d_a_t_a_._h_p_p" │ │ │ │ │ -add_torrent_params rreeaadd__rreessuummee__ddaattaa (span buffer │ │ │ │ │ - , load_torrent_limits const& cfg = {}); │ │ │ │ │ add_torrent_params rreeaadd__rreessuummee__ddaattaa (bdecode_node const& rd │ │ │ │ │ , int piece_limit = 0x200000); │ │ │ │ │ -add_torrent_params rreeaadd__rreessuummee__ddaattaa (bdecode_node const& rd │ │ │ │ │ - , error_code& ec, int piece_limit = 0x200000); │ │ │ │ │ +add_torrent_params rreeaadd__rreessuummee__ddaattaa (span buffer │ │ │ │ │ + , load_torrent_limits const& cfg = {}); │ │ │ │ │ add_torrent_params rreeaadd__rreessuummee__ddaattaa (span buffer │ │ │ │ │ , error_code& ec, load_torrent_limits const& cfg = {}); │ │ │ │ │ +add_torrent_params rreeaadd__rreessuummee__ddaattaa (bdecode_node const& rd │ │ │ │ │ + , error_code& ec, int piece_limit = 0x200000); │ │ │ │ │ these functions are used to parse resume data and populate the appropriate │ │ │ │ │ fields in an _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s object. This object can then be used to add the │ │ │ │ │ actual _t_o_r_r_e_n_t___i_n_f_o object to and pass to session::add_torrent() or session:: │ │ │ │ │ async_add_torrent(). │ │ │ │ │ If the client wants to override any field that was loaded from the resume data, │ │ │ │ │ e.g. save_path, those fields must be changed after loading resume data but │ │ │ │ │ before adding the torrent. │ │ │ │ │ @@ -29,28 +29,28 @@ │ │ │ │ │ the torrent that may be loaded as part of the resume data, if it contains an │ │ │ │ │ info field. The overloads that take a flat buffer are instead configured with │ │ │ │ │ limits on torrent sizes via load_torrent limits. │ │ │ │ │ In order to support large torrents, it may also be necessary to raise the │ │ │ │ │ _s_e_t_t_i_n_g_s___p_a_c_k_:_:_m_a_x___p_i_e_c_e___c_o_u_n_t setting and pass a higher limit to calls to │ │ │ │ │ _t_o_r_r_e_n_t___i_n_f_o_:_:_p_a_r_s_e___i_n_f_o___s_e_c_t_i_o_n_(_). │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -************ wwrriittee__rreessuummee__ddaattaa__bbuuff(()) wwrriittee__rreessuummee__ddaattaa(()) ************ │ │ │ │ │ +************ wwrriittee__rreessuummee__ddaattaa(()) wwrriittee__rreessuummee__ddaattaa__bbuuff(()) ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_w_r_i_t_e___r_e_s_u_m_e___d_a_t_a_._h_p_p" │ │ │ │ │ -entry wwrriittee__rreessuummee__ddaattaa (add_torrent_params const& atp); │ │ │ │ │ std::vector wwrriittee__rreessuummee__ddaattaa__bbuuff (add_torrent_params const& atp); │ │ │ │ │ +entry wwrriittee__rreessuummee__ddaattaa (add_torrent_params const& atp); │ │ │ │ │ this function turns the resume data in an add_torrent_params object into a │ │ │ │ │ bencoded structure │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ wwrriittee__ttoorrrreenntt__ffiillee(()) wwrriittee__ttoorrrreenntt__ffiillee__bbuuff(()) ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_w_r_i_t_e___r_e_s_u_m_e___d_a_t_a_._h_p_p" │ │ │ │ │ entry wwrriittee__ttoorrrreenntt__ffiillee (add_torrent_params const& atp); │ │ │ │ │ -std::vector wwrriittee__ttoorrrreenntt__ffiillee__bbuuff (add_torrent_params const& atp │ │ │ │ │ - , write_torrent_flags_t flags); │ │ │ │ │ entry wwrriittee__ttoorrrreenntt__ffiillee (add_torrent_params const& atp, write_torrent_flags_t │ │ │ │ │ flags); │ │ │ │ │ +std::vector wwrriittee__ttoorrrreenntt__ffiillee__bbuuff (add_torrent_params const& atp │ │ │ │ │ + , write_torrent_flags_t flags); │ │ │ │ │ writes only the fields to create a .torrent file. This function may fail with a │ │ │ │ │ std::system_error exception if: │ │ │ │ │ * The _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s object passed to this function does not contain │ │ │ │ │ the info dictionary (the ti field) │ │ │ │ │ * The piece layers are not complete for all files that need them │ │ │ │ │ The write_torrent_file_buf() overload returns the torrent file in bencoded │ │ │ │ │ buffer form. This overload may be faster at the expense of lost flexibility to │ │ │ ├── ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Session.html │ │ │ │ @@ -29,15 +29,15 @@ │ │ │ │ │ │ │ │ │ │ │ │

      home

      │ │ │ │
      │ │ │ │

      Table of contents

      │ │ │ │ │ │ │ │
      │ │ │ │ [report issue]
      │ │ │ │

      session_proxy

      │ │ │ │

      Declared in "libtorrent/session.hpp"

      │ │ │ │

      this is a holder for the internal session implementation object. Once the │ │ │ │ session destruction is explicitly initiated, this holder is used to │ │ │ │ synchronize the completion of the shutdown. The lifetime of this object │ │ │ │ may outlive session, causing the session destructor to not block. The │ │ │ │ session_proxy destructor will block however, until the underlying session │ │ │ │ is done shutting down.

      │ │ │ │
      │ │ │ │  struct session_proxy
      │ │ │ │  {
      │ │ │ │ -   session_proxy (session_proxy const&);
      │ │ │ │ -   ~session_proxy ();
      │ │ │ │     session_proxy& operator= (session_proxy const&) &;
      │ │ │ │ +   ~session_proxy ();
      │ │ │ │     session_proxy& operator= (session_proxy&&) & noexcept;
      │ │ │ │ -   session_proxy ();
      │ │ │ │ +   session_proxy (session_proxy const&);
      │ │ │ │     session_proxy (session_proxy&&) noexcept;
      │ │ │ │ +   session_proxy ();
      │ │ │ │  };
      │ │ │ │  
      │ │ │ │ - │ │ │ │ + │ │ │ │ │ │ │ │ -[report issue]
      │ │ │ │ -

      operator=() ~session_proxy() session_proxy()

      │ │ │ │ +[report issue]
      │ │ │ │ +

      session_proxy() ~session_proxy() operator=()

      │ │ │ │
      │ │ │ │ -session_proxy (session_proxy const&);
      │ │ │ │ -~session_proxy ();
      │ │ │ │  session_proxy& operator= (session_proxy const&) &;
      │ │ │ │ +~session_proxy ();
      │ │ │ │  session_proxy& operator= (session_proxy&&) & noexcept;
      │ │ │ │ -session_proxy ();
      │ │ │ │ +session_proxy (session_proxy const&);
      │ │ │ │  session_proxy (session_proxy&&) noexcept;
      │ │ │ │ +session_proxy ();
      │ │ │ │  
      │ │ │ │

      default constructor, does not refer to any session │ │ │ │ implementation object.

      │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │
      │ │ │ │

      session

      │ │ │ │ @@ -141,49 +141,49 @@ │ │ │ │

      see apply_settings().

      │ │ │ │
      │ │ │ │  struct session : session_handle
      │ │ │ │  {
      │ │ │ │     session (session_params&& params, session_flags_t flags);
      │ │ │ │     session ();
      │ │ │ │     explicit session (session_params&& params);
      │ │ │ │ -   explicit session (session_params const& params);
      │ │ │ │     session (session_params const& params, session_flags_t flags);
      │ │ │ │ -   session (session_params&& params, io_context& ios);
      │ │ │ │ -   session (session_params&& params, io_context& ios, session_flags_t);
      │ │ │ │ +   explicit session (session_params const& params);
      │ │ │ │     session (session_params const& params, io_context& ios);
      │ │ │ │ +   session (session_params&& params, io_context& ios, session_flags_t);
      │ │ │ │     session (session_params const& params, io_context& ios, session_flags_t);
      │ │ │ │ +   session (session_params&& params, io_context& ios);
      │ │ │ │     ~session ();
      │ │ │ │     session_proxy abort ();
      │ │ │ │  };
      │ │ │ │  
      │ │ │ │ [report issue]
      │ │ │ │

      session()

      │ │ │ │
      │ │ │ │  session (session_params&& params, session_flags_t flags);
      │ │ │ │  session ();
      │ │ │ │  explicit session (session_params&& params);
      │ │ │ │ -explicit session (session_params const& params);
      │ │ │ │  session (session_params const& params, session_flags_t flags);
      │ │ │ │ +explicit session (session_params const& params);
      │ │ │ │  
      │ │ │ │

      Constructs the session objects which acts as the container of torrents. │ │ │ │ In order to avoid a race condition between starting the session and │ │ │ │ configuring it, you can pass in a session_params object. Its settings │ │ │ │ will take effect before the session starts up.

      │ │ │ │

      The overloads taking flags can be used to start a session in │ │ │ │ paused mode (by passing in session::paused). Note that │ │ │ │ add_default_plugins do not have an affect on constructors that │ │ │ │ take a session_params object. It already contains the plugins to use.

      │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      session()

      │ │ │ │
      │ │ │ │ -session (session_params&& params, io_context& ios);
      │ │ │ │ -session (session_params&& params, io_context& ios, session_flags_t);
      │ │ │ │  session (session_params const& params, io_context& ios);
      │ │ │ │ +session (session_params&& params, io_context& ios, session_flags_t);
      │ │ │ │  session (session_params const& params, io_context& ios, session_flags_t);
      │ │ │ │ +session (session_params&& params, io_context& ios);
      │ │ │ │  
      │ │ │ │

      Overload of the constructor that takes an external io_context to run │ │ │ │ the session object on. This is primarily useful for tests that may want │ │ │ │ to run multiple sessions on a single io_context, or low resource │ │ │ │ systems where additional threads are expensive and sharing an │ │ │ │ io_context with other events is fine.

      │ │ │ │
      │ │ │ │ @@ -233,17 +233,17 @@ │ │ │ │

      session_params

      │ │ │ │

      Declared in "libtorrent/session_params.hpp"

      │ │ │ │

      The session_params is a parameters pack for configuring the session │ │ │ │ before it's started.

      │ │ │ │
      │ │ │ │  struct session_params
      │ │ │ │  {
      │ │ │ │ -   session_params ();
      │ │ │ │ -   session_params (settings_pack const& sp);
      │ │ │ │     session_params (settings_pack&& sp);
      │ │ │ │ +   session_params (settings_pack const& sp);
      │ │ │ │ +   session_params ();
      │ │ │ │     session_params (settings_pack&& sp
      │ │ │ │        , std::vector<std::shared_ptr<plugin>> exts);
      │ │ │ │     session_params (settings_pack const& sp
      │ │ │ │        , std::vector<std::shared_ptr<plugin>> exts);
      │ │ │ │  
      │ │ │ │     settings_pack settings;
      │ │ │ │     std::vector<std::shared_ptr<plugin>> extensions;
      │ │ │ │ @@ -253,17 +253,17 @@
      │ │ │ │     std::map<std::string, std::string> ext_state;
      │ │ │ │     libtorrent::ip_filter ip_filter;
      │ │ │ │  };
      │ │ │ │  
      │ │ │ │ [report issue]
      │ │ │ │

      session_params()

      │ │ │ │
      │ │ │ │ -session_params ();
      │ │ │ │ -session_params (settings_pack const& sp);
      │ │ │ │  session_params (settings_pack&& sp);
      │ │ │ │ +session_params (settings_pack const& sp);
      │ │ │ │ +session_params ();
      │ │ │ │  
      │ │ │ │

      This constructor can be used to start with the default plugins │ │ │ │ (ut_metadata, ut_pex and smart_ban). Pass a settings_pack to set the │ │ │ │ initial settings when the session starts.

      │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      session_params()

      │ │ │ │ @@ -328,65 +328,65 @@ │ │ │ │ void refresh_torrent_status (std::vector<torrent_status>* ret │ │ │ │ , status_flags_t flags = {}) const; │ │ │ │ void post_torrent_updates (status_flags_t flags = status_flags_t::all()); │ │ │ │ void post_session_stats (); │ │ │ │ void post_dht_stats (); │ │ │ │ void set_dht_state (dht::dht_state&& st); │ │ │ │ void set_dht_state (dht::dht_state const& st); │ │ │ │ - std::vector<torrent_handle> get_torrents () const; │ │ │ │ torrent_handle find_torrent (sha1_hash const& info_hash) const; │ │ │ │ + std::vector<torrent_handle> get_torrents () const; │ │ │ │ + torrent_handle add_torrent (add_torrent_params&& params, error_code& ec); │ │ │ │ void async_add_torrent (add_torrent_params const& params); │ │ │ │ - torrent_handle add_torrent (add_torrent_params const& params); │ │ │ │ void async_add_torrent (add_torrent_params&& params); │ │ │ │ torrent_handle add_torrent (add_torrent_params&& params); │ │ │ │ + torrent_handle add_torrent (add_torrent_params const& params); │ │ │ │ torrent_handle add_torrent (add_torrent_params const& params, error_code& ec); │ │ │ │ - torrent_handle add_torrent (add_torrent_params&& params, error_code& ec); │ │ │ │ - void pause (); │ │ │ │ bool is_paused () const; │ │ │ │ void resume (); │ │ │ │ + void pause (); │ │ │ │ bool is_dht_running () const; │ │ │ │ void set_dht_storage (dht::dht_storage_constructor_type sc); │ │ │ │ void add_dht_node (std::pair<std::string, int> const& node); │ │ │ │ void dht_get_item (sha1_hash const& target); │ │ │ │ void dht_get_item (std::array<char, 32> key │ │ │ │ , std::string salt = std::string()); │ │ │ │ sha1_hash dht_put_item (entry data); │ │ │ │ void dht_put_item (std::array<char, 32> key │ │ │ │ , std::function<void(entry&, std::array<char, 64>& │ │ │ │ , std::int64_t&, std::string const&)> cb │ │ │ │ , std::string salt = std::string()); │ │ │ │ - void dht_get_peers (sha1_hash const& info_hash); │ │ │ │ void dht_announce (sha1_hash const& info_hash, int port = 0, dht::announce_flags_t flags = {}); │ │ │ │ + void dht_get_peers (sha1_hash const& info_hash); │ │ │ │ void dht_live_nodes (sha1_hash const& nid); │ │ │ │ void dht_sample_infohashes (udp::endpoint const& ep, sha1_hash const& target); │ │ │ │ void dht_direct_request (udp::endpoint const& ep, entry const& e, client_data_t userdata = {}); │ │ │ │ + void add_extension (std::shared_ptr<plugin> ext); │ │ │ │ void add_extension (std::function<std::shared_ptr<torrent_plugin>( │ │ │ │ torrent_handle const&, client_data_t)> ext); │ │ │ │ - void add_extension (std::shared_ptr<plugin> ext); │ │ │ │ ip_filter get_ip_filter () const; │ │ │ │ void set_ip_filter (ip_filter f); │ │ │ │ void set_port_filter (port_filter const& f); │ │ │ │ unsigned short listen_port () const; │ │ │ │ bool is_listening () const; │ │ │ │ unsigned short ssl_listen_port () const; │ │ │ │ ip_filter get_peer_class_filter () const; │ │ │ │ void set_peer_class_filter (ip_filter const& f); │ │ │ │ - peer_class_type_filter get_peer_class_type_filter () const; │ │ │ │ void set_peer_class_type_filter (peer_class_type_filter const& f); │ │ │ │ + peer_class_type_filter get_peer_class_type_filter () const; │ │ │ │ peer_class_t create_peer_class (char const* name); │ │ │ │ void delete_peer_class (peer_class_t cid); │ │ │ │ peer_class_info get_peer_class (peer_class_t cid) const; │ │ │ │ void set_peer_class (peer_class_t cid, peer_class_info const& pci); │ │ │ │ void remove_torrent (const torrent_handle&, remove_flags_t = {}); │ │ │ │ + void apply_settings (settings_pack&&); │ │ │ │ settings_pack get_settings () const; │ │ │ │ void apply_settings (settings_pack const&); │ │ │ │ - void apply_settings (settings_pack&&); │ │ │ │ void pop_alerts (std::vector<alert*>* alerts); │ │ │ │ - alert* wait_for_alert (time_duration max_wait); │ │ │ │ void set_alert_notify (std::function<void()> const& fun); │ │ │ │ + alert* wait_for_alert (time_duration max_wait); │ │ │ │ std::vector<port_mapping_t> add_port_mapping (portmap_protocol t, int external_port, int local_port); │ │ │ │ void delete_port_mapping (port_mapping_t handle); │ │ │ │ void reopen_network_sockets (reopen_network_flags_t options = reopen_map_ports); │ │ │ │ std::shared_ptr<aux::session_impl> native_handle () const; │ │ │ │ │ │ │ │ static constexpr save_state_flags_t save_settings = 0_bit; │ │ │ │ static constexpr save_state_flags_t save_dht_state = 2_bit; │ │ │ │ @@ -512,36 +512,36 @@ │ │ │ │ next time the DHT is started, as if it had been passed in via the │ │ │ │ session_params on startup.

      │ │ │ │ │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      get_torrents() find_torrent()

      │ │ │ │
      │ │ │ │ -std::vector<torrent_handle> get_torrents () const;
      │ │ │ │  torrent_handle find_torrent (sha1_hash const& info_hash) const;
      │ │ │ │ +std::vector<torrent_handle> get_torrents () const;
      │ │ │ │  
      │ │ │ │

      find_torrent() looks for a torrent with the given info-hash. In │ │ │ │ case there is such a torrent in the session, a torrent_handle to that │ │ │ │ torrent is returned. In case the torrent cannot be found, an invalid │ │ │ │ torrent_handle is returned.

      │ │ │ │

      See torrent_handle::is_valid() to know if the torrent was found or │ │ │ │ not.

      │ │ │ │

      get_torrents() returns a vector of torrent_handles to all the │ │ │ │ torrents currently in the session.

      │ │ │ │ - │ │ │ │ -[report issue]
      │ │ │ │ -
      │ │ │ │ -

      async_add_torrent() add_torrent()

      │ │ │ │ + │ │ │ │ +[report issue]
      │ │ │ │ +
      │ │ │ │ +

      add_torrent() async_add_torrent()

      │ │ │ │
      │ │ │ │ +torrent_handle add_torrent (add_torrent_params&& params, error_code& ec);
      │ │ │ │  void async_add_torrent (add_torrent_params const& params);
      │ │ │ │ -torrent_handle add_torrent (add_torrent_params const& params);
      │ │ │ │  void async_add_torrent (add_torrent_params&& params);
      │ │ │ │  torrent_handle add_torrent (add_torrent_params&& params);
      │ │ │ │ +torrent_handle add_torrent (add_torrent_params const& params);
      │ │ │ │  torrent_handle add_torrent (add_torrent_params const& params, error_code& ec);
      │ │ │ │ -torrent_handle add_torrent (add_torrent_params&& params, error_code& ec);
      │ │ │ │  
      │ │ │ │

      You add torrents through the add_torrent() function where you give an │ │ │ │ object with all the parameters. The add_torrent() overloads will block │ │ │ │ until the torrent has been added (or failed to be added) and returns │ │ │ │ an error code and a torrent_handle. In order to add torrents more │ │ │ │ efficiently, consider using async_add_torrent() which returns │ │ │ │ immediately, without waiting for the torrent to add. Notification of │ │ │ │ @@ -566,23 +566,23 @@ │ │ │ │ want to control are torrent_flags::paused and │ │ │ │ torrent_flags::auto_managed. In order to add a magnet link that will │ │ │ │ just download the metadata, but no payload, set the │ │ │ │ torrent_flags::upload_mode flag.

      │ │ │ │

      Special consideration has to be taken when adding hybrid torrents │ │ │ │ (i.e. torrents that are BitTorrent v2 torrents that are backwards │ │ │ │ compatible with v1). For more details, see BitTorrent v2 torrents.

      │ │ │ │ - │ │ │ │ + │ │ │ │ │ │ │ │ -[report issue]
      │ │ │ │ -
      │ │ │ │ -

      pause() is_paused() resume()

      │ │ │ │ +[report issue]
      │ │ │ │ +
      │ │ │ │ +

      resume() is_paused() pause()

      │ │ │ │
      │ │ │ │ -void pause ();
      │ │ │ │  bool is_paused () const;
      │ │ │ │  void resume ();
      │ │ │ │ +void pause ();
      │ │ │ │  
      │ │ │ │

      Pausing the session has the same effect as pausing every torrent in │ │ │ │ it, except that torrents will not be resumed by the auto-manage │ │ │ │ mechanism. Resuming will restore the torrents to their previous paused │ │ │ │ state. i.e. the session pause state is separate from the torrent pause │ │ │ │ state. A torrent is inactive if it is paused or if the session is │ │ │ │ paused.

      │ │ │ │ @@ -695,16 +695,16 @@ │ │ │ │ the DHT works, it is natural to always do a lookup before storing and │ │ │ │ calling the callback in between is convenient.

      │ │ │ │ │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      dht_get_peers() dht_announce()

      │ │ │ │
      │ │ │ │ -void dht_get_peers (sha1_hash const& info_hash);
      │ │ │ │  void dht_announce (sha1_hash const& info_hash, int port = 0, dht::announce_flags_t flags = {});
      │ │ │ │ +void dht_get_peers (sha1_hash const& info_hash);
      │ │ │ │  
      │ │ │ │

      dht_get_peers() will issue a DHT get_peer request to the DHT for the │ │ │ │ specified info-hash. The response (the peers) will be posted back in a │ │ │ │ dht_get_peers_reply_alert.

      │ │ │ │

      dht_announce() will issue a DHT announce request to the DHT to the │ │ │ │ specified info-hash, advertising the specified port. If the port is │ │ │ │ left at its default, 0, the port will be implied by the DHT message's │ │ │ │ @@ -749,17 +749,17 @@ │ │ │ │ with the response (if any) and the userdata pointer passed in here. │ │ │ │ Since this alert is a response to an explicit call, it will always be │ │ │ │ posted, regardless of the alert mask.

      │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      add_extension()

      │ │ │ │
      │ │ │ │ +void add_extension (std::shared_ptr<plugin> ext);
      │ │ │ │  void add_extension (std::function<std::shared_ptr<torrent_plugin>(
      │ │ │ │        torrent_handle const&, client_data_t)> ext);
      │ │ │ │ -void add_extension (std::shared_ptr<plugin> ext);
      │ │ │ │  
      │ │ │ │

      This function adds an extension to this session. The argument is a │ │ │ │ function object that is called with a torrent_handle and which should │ │ │ │ return a std::shared_ptr<torrent_plugin>. To write custom │ │ │ │ plugins, see libtorrent plugins. For the typical bittorrent client │ │ │ │ all of these extensions should be added. The main plugins implemented │ │ │ │ in libtorrent are:

      │ │ │ │ @@ -812,34 +812,34 @@ │ │ │ │
      │ │ │ │  void set_port_filter (port_filter const& f);
      │ │ │ │  
      │ │ │ │

      apply port_filter f to incoming and outgoing peers. a port filter │ │ │ │ will reject making outgoing peer connections to certain remote ports. │ │ │ │ The main intention is to be able to avoid triggering certain │ │ │ │ anti-virus software by connecting to SMTP, FTP ports.

      │ │ │ │ - │ │ │ │ + │ │ │ │ │ │ │ │ -[report issue]
      │ │ │ │ -
      │ │ │ │ -

      listen_port() is_listening() ssl_listen_port()

      │ │ │ │ +[report issue]
      │ │ │ │ +
      │ │ │ │ +

      ssl_listen_port() is_listening() listen_port()

      │ │ │ │
      │ │ │ │  unsigned short listen_port () const;
      │ │ │ │  bool is_listening () const;
      │ │ │ │  unsigned short ssl_listen_port () const;
      │ │ │ │  
      │ │ │ │

      is_listening() will tell you whether or not the session has │ │ │ │ successfully opened a listening port. If it hasn't, this function will │ │ │ │ return false, and then you can set a new │ │ │ │ settings_pack::listen_interfaces to try another interface and port to │ │ │ │ bind to.

      │ │ │ │

      listen_port() returns the port we ended up listening on.

      │ │ │ │ - │ │ │ │ -[report issue]
      │ │ │ │ -
      │ │ │ │ -

      get_peer_class_filter() set_peer_class_filter()

      │ │ │ │ + │ │ │ │ +[report issue]
      │ │ │ │ +
      │ │ │ │ +

      set_peer_class_filter() get_peer_class_filter()

      │ │ │ │
      │ │ │ │  ip_filter get_peer_class_filter () const;
      │ │ │ │  void set_peer_class_filter (ip_filter const& f);
      │ │ │ │  
      │ │ │ │

      Sets the peer class filter for this session. All new peer connections │ │ │ │ will take this into account and be added to the peer classes specified │ │ │ │ by this filter, based on the peer's IP address.

      │ │ │ │ @@ -867,16 +867,16 @@ │ │ │ │

      The get_peer_class_filter() function returns the current filter.

      │ │ │ │

      For more information, see peer classes.

      │ │ │ │ │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      set_peer_class_type_filter() get_peer_class_type_filter()

      │ │ │ │
      │ │ │ │ -peer_class_type_filter get_peer_class_type_filter () const;
      │ │ │ │  void set_peer_class_type_filter (peer_class_type_filter const& f);
      │ │ │ │ +peer_class_type_filter get_peer_class_type_filter () const;
      │ │ │ │  
      │ │ │ │

      Sets and gets the peer class type filter. This is controls automatic │ │ │ │ peer class assignments to peers based on what kind of socket it is.

      │ │ │ │

      It does not only support assigning peer classes, it also supports │ │ │ │ removing peer classes based on socket type.

      │ │ │ │

      The order of these rules being applied are:

      │ │ │ │
        │ │ │ │ @@ -944,28 +944,28 @@ │ │ │ │
        │ │ │ │  void remove_torrent (const torrent_handle&, remove_flags_t = {});
        │ │ │ │  
        │ │ │ │

        remove_torrent() will close all peer connections associated with │ │ │ │ the torrent and tell the tracker that we've stopped participating in │ │ │ │ the swarm. This operation cannot fail. When it completes, you will │ │ │ │ receive a torrent_removed_alert.

        │ │ │ │ -

        remove_torrent() is non-blocking, but will remove the torrent from the │ │ │ │ +

        remove_torrent() is non-blocking, but will remove the torrent from the │ │ │ │ session synchronously. Calling session_handle::add_torrent() immediately │ │ │ │ afterward with the same torrent will succeed. Note that this creates a │ │ │ │ new handle which is not equal to the removed one.

        │ │ │ │

        The optional second argument options can be used to delete all the │ │ │ │ files downloaded by this torrent. To do so, pass in the value │ │ │ │ session_handle::delete_files. Once the torrent is deleted, a │ │ │ │ torrent_deleted_alert is posted.

        │ │ │ │ -

        The torrent_handle remains valid for some time after remove_torrent() is │ │ │ │ +

        The torrent_handle remains valid for some time after remove_torrent() is │ │ │ │ called. It will become invalid only after all libtorrent tasks (such as │ │ │ │ I/O tasks) release their references to the torrent. Until this happens, │ │ │ │ torrent_handle::is_valid() will return true, and other calls such │ │ │ │ as torrent_handle::status() will succeed. Because of this, and because │ │ │ │ -remove_torrent() is non-blocking, the following sequence usually │ │ │ │ +remove_torrent() is non-blocking, the following sequence usually │ │ │ │ succeeds (does not throw system_error): │ │ │ │ .. code:: c++

        │ │ │ │
        │ │ │ │ session.remove_handle(handle); │ │ │ │ handle.save_resume_data();
        │ │ │ │

        Note that when a queued or downloading torrent is removed, its position │ │ │ │ in the download queue is vacated and every subsequent torrent in the │ │ │ │ @@ -974,30 +974,30 @@ │ │ │ │ advised to remove them from the back of the queue, to minimize the │ │ │ │ shifting.

        │ │ │ │ │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      apply_settings() get_settings()

      │ │ │ │
      │ │ │ │ +void apply_settings (settings_pack&&);
      │ │ │ │  settings_pack get_settings () const;
      │ │ │ │  void apply_settings (settings_pack const&);
      │ │ │ │ -void apply_settings (settings_pack&&);
      │ │ │ │  
      │ │ │ │

      Applies the settings specified by the settings_pack s. This is an │ │ │ │ asynchronous operation that will return immediately and actually apply │ │ │ │ the settings to the main thread of libtorrent some time later.

      │ │ │ │ │ │ │ │ - │ │ │ │ -[report issue]
      │ │ │ │ -
      │ │ │ │ -

      wait_for_alert() pop_alerts() set_alert_notify()

      │ │ │ │ + │ │ │ │ +[report issue]
      │ │ │ │ +
      │ │ │ │ +

      wait_for_alert() set_alert_notify() pop_alerts()

      │ │ │ │
      │ │ │ │  void pop_alerts (std::vector<alert*>* alerts);
      │ │ │ │ -alert* wait_for_alert (time_duration max_wait);
      │ │ │ │  void set_alert_notify (std::function<void()> const& fun);
      │ │ │ │ +alert* wait_for_alert (time_duration max_wait);
      │ │ │ │  
      │ │ │ │

      Alerts is the main mechanism for libtorrent to report errors and │ │ │ │ events. pop_alerts fills in the vector passed to it with pointers │ │ │ │ to new alerts. The session still owns these alerts and they will stay │ │ │ │ valid until the next time pop_alerts is called. You may not delete │ │ │ │ the alert objects.

      │ │ │ │

      It is safe to call pop_alerts from multiple different threads, as │ │ │ │ @@ -1123,30 +1123,30 @@ │ │ │ │ [report issue]

      │ │ │ │
      reopen_map_ports
      │ │ │ │
      This option indicates if the ports are mapped using natpmp │ │ │ │ and upnp. If mapping was already made, they are deleted and added │ │ │ │ again. This only works if natpmp and/or upnp are configured to be │ │ │ │ enable.
      │ │ │ │
      │ │ │ │ + │ │ │ │ │ │ │ │ - │ │ │ │ -[report issue]
      │ │ │ │ +[report issue]
      │ │ │ │
      │ │ │ │ -
      │ │ │ │ -

      read_session_params() write_session_params() write_session_params_buf()

      │ │ │ │ +
      │ │ │ │ +

      write_session_params_buf() read_session_params() write_session_params()

      │ │ │ │

      Declared in "libtorrent/session_params.hpp"

      │ │ │ │
      │ │ │ │ -session_params read_session_params (bdecode_node const& e
      │ │ │ │ +std::vector<char> write_session_params_buf (session_params const& sp
      │ │ │ │     , save_state_flags_t flags = save_state_flags_t::all());
      │ │ │ │  entry write_session_params (session_params const& sp
      │ │ │ │     , save_state_flags_t flags = save_state_flags_t::all());
      │ │ │ │ -std::vector<char> write_session_params_buf (session_params const& sp
      │ │ │ │ -   , save_state_flags_t flags = save_state_flags_t::all());
      │ │ │ │  session_params read_session_params (span<char const> buf
      │ │ │ │     , save_state_flags_t flags = save_state_flags_t::all());
      │ │ │ │ +session_params read_session_params (bdecode_node const& e
      │ │ │ │ +   , save_state_flags_t flags = save_state_flags_t::all());
      │ │ │ │  
      │ │ │ │

      These functions serialize and de-serialize a session_params object to and │ │ │ │ from bencoded form. The session_params object is used to initialize a new │ │ │ │ session using the state from a previous one (or by programmatically configure │ │ │ │ the session up-front). │ │ │ │ The flags parameter can be used to only save and load certain aspects of the │ │ │ │ session's state. │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -1,14 +1,14 @@ │ │ │ │ │ > │ │ │ │ │ _[_l_i_b_t_o_r_r_e_n_t_ _l_o_g_o_] │ │ │ │ │ VVeerrssiioonn:: 2.0.11 │ │ │ │ │ _h_o_m_e │ │ │ │ │ Table of contents │ │ │ │ │ * _s_e_s_s_i_o_n___p_r_o_x_y │ │ │ │ │ - o _o_p_e_r_a_t_o_r_=_(_)_ _~_s_e_s_s_i_o_n___p_r_o_x_y_(_)_ _s_e_s_s_i_o_n___p_r_o_x_y_(_) │ │ │ │ │ + o _s_e_s_s_i_o_n___p_r_o_x_y_(_)_ _~_s_e_s_s_i_o_n___p_r_o_x_y_(_)_ _o_p_e_r_a_t_o_r_=_(_) │ │ │ │ │ * _s_e_s_s_i_o_n │ │ │ │ │ o _s_e_s_s_i_o_n_(_) │ │ │ │ │ o _s_e_s_s_i_o_n_(_) │ │ │ │ │ o _~_s_e_s_s_i_o_n_(_) │ │ │ │ │ o _a_b_o_r_t_(_) │ │ │ │ │ * _s_e_s_s_i_o_n___p_a_r_a_m_s │ │ │ │ │ o _s_e_s_s_i_o_n___p_a_r_a_m_s_(_) │ │ │ │ │ @@ -18,69 +18,69 @@ │ │ │ │ │ o _s_e_s_s_i_o_n___s_t_a_t_e_(_) │ │ │ │ │ o _g_e_t___t_o_r_r_e_n_t___s_t_a_t_u_s_(_)_ _r_e_f_r_e_s_h___t_o_r_r_e_n_t___s_t_a_t_u_s_(_) │ │ │ │ │ o _p_o_s_t___t_o_r_r_e_n_t___u_p_d_a_t_e_s_(_) │ │ │ │ │ o _p_o_s_t___s_e_s_s_i_o_n___s_t_a_t_s_(_) │ │ │ │ │ o _p_o_s_t___d_h_t___s_t_a_t_s_(_) │ │ │ │ │ o _s_e_t___d_h_t___s_t_a_t_e_(_) │ │ │ │ │ o _g_e_t___t_o_r_r_e_n_t_s_(_)_ _f_i_n_d___t_o_r_r_e_n_t_(_) │ │ │ │ │ - o _a_s_y_n_c___a_d_d___t_o_r_r_e_n_t_(_)_ _a_d_d___t_o_r_r_e_n_t_(_) │ │ │ │ │ - o _p_a_u_s_e_(_)_ _i_s___p_a_u_s_e_d_(_)_ _r_e_s_u_m_e_(_) │ │ │ │ │ + o _a_d_d___t_o_r_r_e_n_t_(_)_ _a_s_y_n_c___a_d_d___t_o_r_r_e_n_t_(_) │ │ │ │ │ + o _r_e_s_u_m_e_(_)_ _i_s___p_a_u_s_e_d_(_)_ _p_a_u_s_e_(_) │ │ │ │ │ o _i_s___d_h_t___r_u_n_n_i_n_g_(_) │ │ │ │ │ o _s_e_t___d_h_t___s_t_o_r_a_g_e_(_) │ │ │ │ │ o _a_d_d___d_h_t___n_o_d_e_(_) │ │ │ │ │ o _d_h_t___g_e_t___i_t_e_m_(_) │ │ │ │ │ o _d_h_t___g_e_t___i_t_e_m_(_) │ │ │ │ │ o _d_h_t___p_u_t___i_t_e_m_(_) │ │ │ │ │ o _d_h_t___p_u_t___i_t_e_m_(_) │ │ │ │ │ o _d_h_t___g_e_t___p_e_e_r_s_(_)_ _d_h_t___a_n_n_o_u_n_c_e_(_) │ │ │ │ │ o _d_h_t___l_i_v_e___n_o_d_e_s_(_) │ │ │ │ │ o _d_h_t___s_a_m_p_l_e___i_n_f_o_h_a_s_h_e_s_(_) │ │ │ │ │ o _d_h_t___d_i_r_e_c_t___r_e_q_u_e_s_t_(_) │ │ │ │ │ o _a_d_d___e_x_t_e_n_s_i_o_n_(_) │ │ │ │ │ o _s_e_t___i_p___f_i_l_t_e_r_(_)_ _g_e_t___i_p___f_i_l_t_e_r_(_) │ │ │ │ │ o _s_e_t___p_o_r_t___f_i_l_t_e_r_(_) │ │ │ │ │ - o _l_i_s_t_e_n___p_o_r_t_(_)_ _i_s___l_i_s_t_e_n_i_n_g_(_)_ _s_s_l___l_i_s_t_e_n___p_o_r_t_(_) │ │ │ │ │ - o _g_e_t___p_e_e_r___c_l_a_s_s___f_i_l_t_e_r_(_)_ _s_e_t___p_e_e_r___c_l_a_s_s___f_i_l_t_e_r_(_) │ │ │ │ │ + o _s_s_l___l_i_s_t_e_n___p_o_r_t_(_)_ _i_s___l_i_s_t_e_n_i_n_g_(_)_ _l_i_s_t_e_n___p_o_r_t_(_) │ │ │ │ │ + o _s_e_t___p_e_e_r___c_l_a_s_s___f_i_l_t_e_r_(_)_ _g_e_t___p_e_e_r___c_l_a_s_s___f_i_l_t_e_r_(_) │ │ │ │ │ o _s_e_t___p_e_e_r___c_l_a_s_s___t_y_p_e___f_i_l_t_e_r_(_)_ _g_e_t___p_e_e_r___c_l_a_s_s___t_y_p_e___f_i_l_t_e_r_(_) │ │ │ │ │ o _c_r_e_a_t_e___p_e_e_r___c_l_a_s_s_(_) │ │ │ │ │ o _d_e_l_e_t_e___p_e_e_r___c_l_a_s_s_(_) │ │ │ │ │ o _s_e_t___p_e_e_r___c_l_a_s_s_(_)_ _g_e_t___p_e_e_r___c_l_a_s_s_(_) │ │ │ │ │ o _r_e_m_o_v_e___t_o_r_r_e_n_t_(_) │ │ │ │ │ o _a_p_p_l_y___s_e_t_t_i_n_g_s_(_)_ _g_e_t___s_e_t_t_i_n_g_s_(_) │ │ │ │ │ - o _w_a_i_t___f_o_r___a_l_e_r_t_(_)_ _p_o_p___a_l_e_r_t_s_(_)_ _s_e_t___a_l_e_r_t___n_o_t_i_f_y_(_) │ │ │ │ │ + o _w_a_i_t___f_o_r___a_l_e_r_t_(_)_ _s_e_t___a_l_e_r_t___n_o_t_i_f_y_(_)_ _p_o_p___a_l_e_r_t_s_(_) │ │ │ │ │ o _d_e_l_e_t_e___p_o_r_t___m_a_p_p_i_n_g_(_)_ _a_d_d___p_o_r_t___m_a_p_p_i_n_g_(_) │ │ │ │ │ o _r_e_o_p_e_n___n_e_t_w_o_r_k___s_o_c_k_e_t_s_(_) │ │ │ │ │ o _n_a_t_i_v_e___h_a_n_d_l_e_(_) │ │ │ │ │ - * _r_e_a_d___s_e_s_s_i_o_n___p_a_r_a_m_s_(_)_ _w_r_i_t_e___s_e_s_s_i_o_n___p_a_r_a_m_s_(_)_ _w_r_i_t_e___s_e_s_s_i_o_n___p_a_r_a_m_s___b_u_f_(_) │ │ │ │ │ + * _w_r_i_t_e___s_e_s_s_i_o_n___p_a_r_a_m_s___b_u_f_(_)_ _r_e_a_d___s_e_s_s_i_o_n___p_a_r_a_m_s_(_)_ _w_r_i_t_e___s_e_s_s_i_o_n___p_a_r_a_m_s_(_) │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ sseessssiioonn__pprrooxxyy ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_s_e_s_s_i_o_n_._h_p_p" │ │ │ │ │ this is a holder for the internal _s_e_s_s_i_o_n implementation object. Once the │ │ │ │ │ _s_e_s_s_i_o_n destruction is explicitly initiated, this holder is used to synchronize │ │ │ │ │ the completion of the shutdown. The lifetime of this object may outlive │ │ │ │ │ _s_e_s_s_i_o_n, causing the _s_e_s_s_i_o_n destructor to not block. The _s_e_s_s_i_o_n___p_r_o_x_y │ │ │ │ │ destructor will block however, until the underlying _s_e_s_s_i_o_n is done shutting │ │ │ │ │ down. │ │ │ │ │ struct session_proxy │ │ │ │ │ { │ │ │ │ │ - sseessssiioonn__pprrooxxyy (session_proxy const&); │ │ │ │ │ - ~~sseessssiioonn__pprrooxxyy (); │ │ │ │ │ session_proxy& ooppeerraattoorr== (session_proxy const&) &; │ │ │ │ │ + ~~sseessssiioonn__pprrooxxyy (); │ │ │ │ │ session_proxy& ooppeerraattoorr== (session_proxy&&) & noexcept; │ │ │ │ │ - sseessssiioonn__pprrooxxyy (); │ │ │ │ │ + sseessssiioonn__pprrooxxyy (session_proxy const&); │ │ │ │ │ sseessssiioonn__pprrooxxyy (session_proxy&&) noexcept; │ │ │ │ │ + sseessssiioonn__pprrooxxyy (); │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** ooppeerraattoorr==(()) ~~sseessssiioonn__pprrooxxyy(()) sseessssiioonn__pprrooxxyy(()) ********** │ │ │ │ │ -sseessssiioonn__pprrooxxyy (session_proxy const&); │ │ │ │ │ -~~sseessssiioonn__pprrooxxyy (); │ │ │ │ │ +********** sseessssiioonn__pprrooxxyy(()) ~~sseessssiioonn__pprrooxxyy(()) ooppeerraattoorr==(()) ********** │ │ │ │ │ session_proxy& ooppeerraattoorr== (session_proxy const&) &; │ │ │ │ │ +~~sseessssiioonn__pprrooxxyy (); │ │ │ │ │ session_proxy& ooppeerraattoorr== (session_proxy&&) & noexcept; │ │ │ │ │ -sseessssiioonn__pprrooxxyy (); │ │ │ │ │ +sseessssiioonn__pprrooxxyy (session_proxy const&); │ │ │ │ │ sseessssiioonn__pprrooxxyy (session_proxy&&) noexcept; │ │ │ │ │ +sseessssiioonn__pprrooxxyy (); │ │ │ │ │ default constructor, does not refer to any _s_e_s_s_i_o_n implementation object. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ sseessssiioonn ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_s_e_s_s_i_o_n_._h_p_p" │ │ │ │ │ The _s_e_s_s_i_o_n holds all state that spans multiple torrents. Among other things it │ │ │ │ │ runs the network loop and manages all torrents. Once it's created, the _s_e_s_s_i_o_n │ │ │ │ │ object will spawn the main thread that will do all the work. The main thread │ │ │ │ │ @@ -91,44 +91,44 @@ │ │ │ │ │ it in to session::apply_settings(). │ │ │ │ │ see _a_p_p_l_y___s_e_t_t_i_n_g_s_(_). │ │ │ │ │ struct session : session_handle │ │ │ │ │ { │ │ │ │ │ sseessssiioonn (session_params&& params, session_flags_t flags); │ │ │ │ │ sseessssiioonn (); │ │ │ │ │ explicit sseessssiioonn (session_params&& params); │ │ │ │ │ - explicit sseessssiioonn (session_params const& params); │ │ │ │ │ sseessssiioonn (session_params const& params, session_flags_t flags); │ │ │ │ │ - sseessssiioonn (session_params&& params, io_context& ios); │ │ │ │ │ - sseessssiioonn (session_params&& params, io_context& ios, session_flags_t); │ │ │ │ │ + explicit sseessssiioonn (session_params const& params); │ │ │ │ │ sseessssiioonn (session_params const& params, io_context& ios); │ │ │ │ │ + sseessssiioonn (session_params&& params, io_context& ios, session_flags_t); │ │ │ │ │ sseessssiioonn (session_params const& params, io_context& ios, session_flags_t); │ │ │ │ │ + sseessssiioonn (session_params&& params, io_context& ios); │ │ │ │ │ ~~sseessssiioonn (); │ │ │ │ │ session_proxy aabboorrtt (); │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** sseessssiioonn(()) ********** │ │ │ │ │ sseessssiioonn (session_params&& params, session_flags_t flags); │ │ │ │ │ sseessssiioonn (); │ │ │ │ │ explicit sseessssiioonn (session_params&& params); │ │ │ │ │ -explicit sseessssiioonn (session_params const& params); │ │ │ │ │ sseessssiioonn (session_params const& params, session_flags_t flags); │ │ │ │ │ +explicit sseessssiioonn (session_params const& params); │ │ │ │ │ Constructs the _s_e_s_s_i_o_n objects which acts as the container of torrents. In │ │ │ │ │ order to avoid a race condition between starting the _s_e_s_s_i_o_n and configuring │ │ │ │ │ it, you can pass in a _s_e_s_s_i_o_n___p_a_r_a_m_s object. Its settings will take effect │ │ │ │ │ before the _s_e_s_s_i_o_n starts up. │ │ │ │ │ The overloads taking flags can be used to start a _s_e_s_s_i_o_n in paused mode (by │ │ │ │ │ passing in session::paused). Note that add_default_plugins do not have an │ │ │ │ │ affect on constructors that take a _s_e_s_s_i_o_n___p_a_r_a_m_s object. It already contains │ │ │ │ │ the plugins to use. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** sseessssiioonn(()) ********** │ │ │ │ │ -sseessssiioonn (session_params&& params, io_context& ios); │ │ │ │ │ -sseessssiioonn (session_params&& params, io_context& ios, session_flags_t); │ │ │ │ │ sseessssiioonn (session_params const& params, io_context& ios); │ │ │ │ │ +sseessssiioonn (session_params&& params, io_context& ios, session_flags_t); │ │ │ │ │ sseessssiioonn (session_params const& params, io_context& ios, session_flags_t); │ │ │ │ │ +sseessssiioonn (session_params&& params, io_context& ios); │ │ │ │ │ Overload of the constructor that takes an external io_context to run the │ │ │ │ │ _s_e_s_s_i_o_n object on. This is primarily useful for tests that may want to run │ │ │ │ │ multiple sessions on a single io_context, or low resource systems where │ │ │ │ │ additional threads are expensive and sharing an io_context with other events is │ │ │ │ │ fine. │ │ │ │ │ Warning │ │ │ │ │ The _s_e_s_s_i_o_n object does not cleanly terminate with an external io_context. The │ │ │ │ │ @@ -162,17 +162,17 @@ │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ************ sseessssiioonn__ppaarraammss ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_s_e_s_s_i_o_n___p_a_r_a_m_s_._h_p_p" │ │ │ │ │ The _s_e_s_s_i_o_n___p_a_r_a_m_s is a parameters pack for configuring the _s_e_s_s_i_o_n before it's │ │ │ │ │ started. │ │ │ │ │ struct session_params │ │ │ │ │ { │ │ │ │ │ - sseessssiioonn__ppaarraammss (); │ │ │ │ │ - sseessssiioonn__ppaarraammss (settings_pack const& sp); │ │ │ │ │ sseessssiioonn__ppaarraammss (settings_pack&& sp); │ │ │ │ │ + sseessssiioonn__ppaarraammss (settings_pack const& sp); │ │ │ │ │ + sseessssiioonn__ppaarraammss (); │ │ │ │ │ sseessssiioonn__ppaarraammss (settings_pack&& sp │ │ │ │ │ , std::vector> exts); │ │ │ │ │ sseessssiioonn__ppaarraammss (settings_pack const& sp │ │ │ │ │ , std::vector> exts); │ │ │ │ │ │ │ │ │ │ settings_pack settings; │ │ │ │ │ std::vector> extensions; │ │ │ │ │ @@ -180,17 +180,17 @@ │ │ │ │ │ dht::dht_storage_constructor_type dht_storage_constructor; │ │ │ │ │ disk_io_constructor_type disk_io_constructor; │ │ │ │ │ std::map ext_state; │ │ │ │ │ libtorrent::ip_filter ip_filter; │ │ │ │ │ }; │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** sseessssiioonn__ppaarraammss(()) ********** │ │ │ │ │ -sseessssiioonn__ppaarraammss (); │ │ │ │ │ -sseessssiioonn__ppaarraammss (settings_pack const& sp); │ │ │ │ │ sseessssiioonn__ppaarraammss (settings_pack&& sp); │ │ │ │ │ +sseessssiioonn__ppaarraammss (settings_pack const& sp); │ │ │ │ │ +sseessssiioonn__ppaarraammss (); │ │ │ │ │ This constructor can be used to start with the default plugins (ut_metadata, │ │ │ │ │ ut_pex and smart_ban). Pass a _s_e_t_t_i_n_g_s___p_a_c_k to set the initial settings when │ │ │ │ │ the _s_e_s_s_i_o_n starts. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** sseessssiioonn__ppaarraammss(()) ********** │ │ │ │ │ sseessssiioonn__ppaarraammss (settings_pack&& sp │ │ │ │ │ , std::vector> exts); │ │ │ │ │ @@ -242,69 +242,69 @@ │ │ │ │ │ void rreeffrreesshh__ttoorrrreenntt__ssttaattuuss (std::vector* ret │ │ │ │ │ , status_flags_t flags = {}) const; │ │ │ │ │ void ppoosstt__ttoorrrreenntt__uuppddaatteess (status_flags_t flags = status_flags_t::all()); │ │ │ │ │ void ppoosstt__sseessssiioonn__ssttaattss (); │ │ │ │ │ void ppoosstt__ddhhtt__ssttaattss (); │ │ │ │ │ void sseett__ddhhtt__ssttaattee (dht::dht_state&& st); │ │ │ │ │ void sseett__ddhhtt__ssttaattee (dht::dht_state const& st); │ │ │ │ │ - std::vector ggeett__ttoorrrreennttss () const; │ │ │ │ │ torrent_handle ffiinndd__ttoorrrreenntt (sha1_hash const& info_hash) const; │ │ │ │ │ + std::vector ggeett__ttoorrrreennttss () const; │ │ │ │ │ + torrent_handle aadddd__ttoorrrreenntt (add_torrent_params&& params, error_code& ec); │ │ │ │ │ void aassyynncc__aadddd__ttoorrrreenntt (add_torrent_params const& params); │ │ │ │ │ - torrent_handle aadddd__ttoorrrreenntt (add_torrent_params const& params); │ │ │ │ │ void aassyynncc__aadddd__ttoorrrreenntt (add_torrent_params&& params); │ │ │ │ │ torrent_handle aadddd__ttoorrrreenntt (add_torrent_params&& params); │ │ │ │ │ + torrent_handle aadddd__ttoorrrreenntt (add_torrent_params const& params); │ │ │ │ │ torrent_handle aadddd__ttoorrrreenntt (add_torrent_params const& params, error_code& │ │ │ │ │ ec); │ │ │ │ │ - torrent_handle aadddd__ttoorrrreenntt (add_torrent_params&& params, error_code& ec); │ │ │ │ │ - void ppaauussee (); │ │ │ │ │ bool iiss__ppaauusseedd () const; │ │ │ │ │ void rreessuummee (); │ │ │ │ │ + void ppaauussee (); │ │ │ │ │ bool iiss__ddhhtt__rruunnnniinngg () const; │ │ │ │ │ void sseett__ddhhtt__ssttoorraaggee (dht::dht_storage_constructor_type sc); │ │ │ │ │ void aadddd__ddhhtt__nnooddee (std::pair const& node); │ │ │ │ │ void ddhhtt__ggeett__iitteemm (sha1_hash const& target); │ │ │ │ │ void ddhhtt__ggeett__iitteemm (std::array key │ │ │ │ │ , std::string salt = std::string()); │ │ │ │ │ sha1_hash ddhhtt__ppuutt__iitteemm (entry data); │ │ │ │ │ void ddhhtt__ppuutt__iitteemm (std::array key │ │ │ │ │ , std::function& │ │ │ │ │ , std::int64_t&, std::string const&)> cb │ │ │ │ │ , std::string salt = std::string()); │ │ │ │ │ - void ddhhtt__ggeett__ppeeeerrss (sha1_hash const& info_hash); │ │ │ │ │ void ddhhtt__aannnnoouunnccee (sha1_hash const& info_hash, int port = 0, dht:: │ │ │ │ │ announce_flags_t flags = {}); │ │ │ │ │ + void ddhhtt__ggeett__ppeeeerrss (sha1_hash const& info_hash); │ │ │ │ │ void ddhhtt__lliivvee__nnooddeess (sha1_hash const& nid); │ │ │ │ │ void ddhhtt__ssaammppllee__iinnffoohhaasshheess (udp::endpoint const& ep, sha1_hash const& │ │ │ │ │ target); │ │ │ │ │ void ddhhtt__ddiirreecctt__rreeqquueesstt (udp::endpoint const& ep, entry const& e, │ │ │ │ │ client_data_t userdata = {}); │ │ │ │ │ + void aadddd__eexxtteennssiioonn (std::shared_ptr ext); │ │ │ │ │ void aadddd__eexxtteennssiioonn (std::function( │ │ │ │ │ torrent_handle const&, client_data_t)> ext); │ │ │ │ │ - void aadddd__eexxtteennssiioonn (std::shared_ptr ext); │ │ │ │ │ ip_filter ggeett__iipp__ffiilltteerr () const; │ │ │ │ │ void sseett__iipp__ffiilltteerr (ip_filter f); │ │ │ │ │ void sseett__ppoorrtt__ffiilltteerr (port_filter const& f); │ │ │ │ │ unsigned short lliisstteenn__ppoorrtt () const; │ │ │ │ │ bool iiss__lliisstteenniinngg () const; │ │ │ │ │ unsigned short ssssll__lliisstteenn__ppoorrtt () const; │ │ │ │ │ ip_filter ggeett__ppeeeerr__ccllaassss__ffiilltteerr () const; │ │ │ │ │ void sseett__ppeeeerr__ccllaassss__ffiilltteerr (ip_filter const& f); │ │ │ │ │ - peer_class_type_filter ggeett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr () const; │ │ │ │ │ void sseett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr (peer_class_type_filter const& f); │ │ │ │ │ + peer_class_type_filter ggeett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr () const; │ │ │ │ │ peer_class_t ccrreeaattee__ppeeeerr__ccllaassss (char const* name); │ │ │ │ │ void ddeelleettee__ppeeeerr__ccllaassss (peer_class_t cid); │ │ │ │ │ peer_class_info ggeett__ppeeeerr__ccllaassss (peer_class_t cid) const; │ │ │ │ │ void sseett__ppeeeerr__ccllaassss (peer_class_t cid, peer_class_info const& pci); │ │ │ │ │ void rreemmoovvee__ttoorrrreenntt (const torrent_handle&, remove_flags_t = {}); │ │ │ │ │ + void aappppllyy__sseettttiinnggss (settings_pack&&); │ │ │ │ │ settings_pack ggeett__sseettttiinnggss () const; │ │ │ │ │ void aappppllyy__sseettttiinnggss (settings_pack const&); │ │ │ │ │ - void aappppllyy__sseettttiinnggss (settings_pack&&); │ │ │ │ │ void ppoopp__aalleerrttss (std::vector* alerts); │ │ │ │ │ - alert* wwaaiitt__ffoorr__aalleerrtt (time_duration max_wait); │ │ │ │ │ void sseett__aalleerrtt__nnoottiiffyy (std::function const& fun); │ │ │ │ │ + alert* wwaaiitt__ffoorr__aalleerrtt (time_duration max_wait); │ │ │ │ │ std::vector aadddd__ppoorrtt__mmaappppiinngg (portmap_protocol t, int │ │ │ │ │ external_port, int local_port); │ │ │ │ │ void ddeelleettee__ppoorrtt__mmaappppiinngg (port_mapping_t handle); │ │ │ │ │ void rreeooppeenn__nneettwwoorrkk__ssoocckkeettss (reopen_network_flags_t options = │ │ │ │ │ reopen_map_ports); │ │ │ │ │ std::shared_ptr nnaattiivvee__hhaannddllee () const; │ │ │ │ │ │ │ │ │ │ @@ -398,30 +398,30 @@ │ │ │ │ │ void sseett__ddhhtt__ssttaattee (dht::dht_state&& st); │ │ │ │ │ void sseett__ddhhtt__ssttaattee (dht::dht_state const& st); │ │ │ │ │ set the DHT state for the _s_e_s_s_i_o_n. This will be taken into account the next │ │ │ │ │ time the DHT is started, as if it had been passed in via the _s_e_s_s_i_o_n___p_a_r_a_m_s on │ │ │ │ │ startup. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** ggeett__ttoorrrreennttss(()) ffiinndd__ttoorrrreenntt(()) ********** │ │ │ │ │ -std::vector ggeett__ttoorrrreennttss () const; │ │ │ │ │ torrent_handle ffiinndd__ttoorrrreenntt (sha1_hash const& info_hash) const; │ │ │ │ │ +std::vector ggeett__ttoorrrreennttss () const; │ │ │ │ │ find_torrent() looks for a torrent with the given info-hash. In case there is │ │ │ │ │ such a torrent in the _s_e_s_s_i_o_n, a _t_o_r_r_e_n_t___h_a_n_d_l_e to that torrent is returned. In │ │ │ │ │ case the torrent cannot be found, an invalid _t_o_r_r_e_n_t___h_a_n_d_l_e is returned. │ │ │ │ │ See torrent_handle::is_valid() to know if the torrent was found or not. │ │ │ │ │ get_torrents() returns a vector of torrent_handles to all the torrents │ │ │ │ │ currently in the _s_e_s_s_i_o_n. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** aassyynncc__aadddd__ttoorrrreenntt(()) aadddd__ttoorrrreenntt(()) ********** │ │ │ │ │ +********** aadddd__ttoorrrreenntt(()) aassyynncc__aadddd__ttoorrrreenntt(()) ********** │ │ │ │ │ +torrent_handle aadddd__ttoorrrreenntt (add_torrent_params&& params, error_code& ec); │ │ │ │ │ void aassyynncc__aadddd__ttoorrrreenntt (add_torrent_params const& params); │ │ │ │ │ -torrent_handle aadddd__ttoorrrreenntt (add_torrent_params const& params); │ │ │ │ │ void aassyynncc__aadddd__ttoorrrreenntt (add_torrent_params&& params); │ │ │ │ │ torrent_handle aadddd__ttoorrrreenntt (add_torrent_params&& params); │ │ │ │ │ +torrent_handle aadddd__ttoorrrreenntt (add_torrent_params const& params); │ │ │ │ │ torrent_handle aadddd__ttoorrrreenntt (add_torrent_params const& params, error_code& ec); │ │ │ │ │ -torrent_handle aadddd__ttoorrrreenntt (add_torrent_params&& params, error_code& ec); │ │ │ │ │ You add torrents through the _a_d_d___t_o_r_r_e_n_t_(_) function where you give an object │ │ │ │ │ with all the parameters. The _a_d_d___t_o_r_r_e_n_t_(_) overloads will block until the │ │ │ │ │ torrent has been added (or failed to be added) and returns an error code and a │ │ │ │ │ _t_o_r_r_e_n_t___h_a_n_d_l_e. In order to add torrents more efficiently, consider using │ │ │ │ │ _a_s_y_n_c___a_d_d___t_o_r_r_e_n_t_(_) which returns immediately, without waiting for the torrent │ │ │ │ │ to add. Notification of the torrent being added is sent as _a_d_d___t_o_r_r_e_n_t___a_l_e_r_t. │ │ │ │ │ The save_path field in _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s must be set to a valid path where the │ │ │ │ │ @@ -442,18 +442,18 @@ │ │ │ │ │ torrent_flags::paused and torrent_flags::auto_managed. In order to add a magnet │ │ │ │ │ link that will just download the metadata, but no payload, set the │ │ │ │ │ torrent_flags::upload_mode flag. │ │ │ │ │ Special consideration has to be taken when adding hybrid torrents (i.e. │ │ │ │ │ torrents that are BitTorrent v2 torrents that are backwards compatible with │ │ │ │ │ v1). For more details, see _B_i_t_T_o_r_r_e_n_t_ _v_2_ _t_o_r_r_e_n_t_s. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** ppaauussee(()) iiss__ppaauusseedd(()) rreessuummee(()) ********** │ │ │ │ │ -void ppaauussee (); │ │ │ │ │ +********** rreessuummee(()) iiss__ppaauusseedd(()) ppaauussee(()) ********** │ │ │ │ │ bool iiss__ppaauusseedd () const; │ │ │ │ │ void rreessuummee (); │ │ │ │ │ +void ppaauussee (); │ │ │ │ │ Pausing the _s_e_s_s_i_o_n has the same effect as pausing every torrent in it, except │ │ │ │ │ that torrents will not be resumed by the auto-manage mechanism. Resuming will │ │ │ │ │ restore the torrents to their previous paused state. i.e. the _s_e_s_s_i_o_n pause │ │ │ │ │ state is separate from the torrent pause state. A torrent is inactive if it is │ │ │ │ │ paused or if the _s_e_s_s_i_o_n is paused. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** iiss__ddhhtt__rruunnnniinngg(()) ********** │ │ │ │ │ @@ -530,17 +530,17 @@ │ │ │ │ │ value is computed via a function instead of just passing in the new value is to │ │ │ │ │ avoid race conditions. If you want to uuppddaattee the value in the DHT, you must │ │ │ │ │ first retrieve it, then modify it, then write it back. The way the DHT works, │ │ │ │ │ it is natural to always do a lookup before storing and calling the callback in │ │ │ │ │ between is convenient. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** ddhhtt__ggeett__ppeeeerrss(()) ddhhtt__aannnnoouunnccee(()) ********** │ │ │ │ │ -void ddhhtt__ggeett__ppeeeerrss (sha1_hash const& info_hash); │ │ │ │ │ void ddhhtt__aannnnoouunnccee (sha1_hash const& info_hash, int port = 0, dht:: │ │ │ │ │ announce_flags_t flags = {}); │ │ │ │ │ +void ddhhtt__ggeett__ppeeeerrss (sha1_hash const& info_hash); │ │ │ │ │ dht_get_peers() will issue a DHT get_peer request to the DHT for the specified │ │ │ │ │ info-hash. The response (the peers) will be posted back in a │ │ │ │ │ _d_h_t___g_e_t___p_e_e_r_s___r_e_p_l_y___a_l_e_r_t. │ │ │ │ │ dht_announce() will issue a DHT announce request to the DHT to the specified │ │ │ │ │ info-hash, advertising the specified port. If the port is left at its default, │ │ │ │ │ 0, the port will be implied by the DHT message's source port (which may improve │ │ │ │ │ connectivity through a NAT). dht_announce() is not affected by the │ │ │ │ │ @@ -572,17 +572,17 @@ │ │ │ │ │ Send an arbitrary DHT request directly to the specified endpoint. This function │ │ │ │ │ is intended for use by plugins. When a response is received or the request │ │ │ │ │ times out, a _d_h_t___d_i_r_e_c_t___r_e_s_p_o_n_s_e___a_l_e_r_t will be posted with the response (if │ │ │ │ │ any) and the userdata pointer passed in here. Since this _a_l_e_r_t is a response to │ │ │ │ │ an explicit call, it will always be posted, regardless of the _a_l_e_r_t mask. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** aadddd__eexxtteennssiioonn(()) ********** │ │ │ │ │ +void aadddd__eexxtteennssiioonn (std::shared_ptr ext); │ │ │ │ │ void aadddd__eexxtteennssiioonn (std::function( │ │ │ │ │ torrent_handle const&, client_data_t)> ext); │ │ │ │ │ -void aadddd__eexxtteennssiioonn (std::shared_ptr ext); │ │ │ │ │ This function adds an extension to this _s_e_s_s_i_o_n. The argument is a function │ │ │ │ │ object that is called with a torrent_handle and which should return a std:: │ │ │ │ │ shared_ptr. To write custom plugins, see _l_i_b_t_o_r_r_e_n_t_ _p_l_u_g_i_n_s. │ │ │ │ │ For the typical bittorrent client all of these extensions should be added. The │ │ │ │ │ main plugins implemented in libtorrent are: │ │ │ │ │ uTorrent metadata │ │ │ │ │ Allows peers to download the metadata (.torrent files) from the swarm │ │ │ │ │ @@ -615,25 +615,25 @@ │ │ │ │ │ ********** sseett__ppoorrtt__ffiilltteerr(()) ********** │ │ │ │ │ void sseett__ppoorrtt__ffiilltteerr (port_filter const& f); │ │ │ │ │ apply _p_o_r_t___f_i_l_t_e_r f to incoming and outgoing peers. a port filter will reject │ │ │ │ │ making outgoing peer connections to certain remote ports. The main intention is │ │ │ │ │ to be able to avoid triggering certain anti-virus software by connecting to │ │ │ │ │ SMTP, FTP ports. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** lliisstteenn__ppoorrtt(()) iiss__lliisstteenniinngg(()) ssssll__lliisstteenn__ppoorrtt(()) ********** │ │ │ │ │ +********** ssssll__lliisstteenn__ppoorrtt(()) iiss__lliisstteenniinngg(()) lliisstteenn__ppoorrtt(()) ********** │ │ │ │ │ unsigned short lliisstteenn__ppoorrtt () const; │ │ │ │ │ bool iiss__lliisstteenniinngg () const; │ │ │ │ │ unsigned short ssssll__lliisstteenn__ppoorrtt () const; │ │ │ │ │ is_listening() will tell you whether or not the _s_e_s_s_i_o_n has successfully opened │ │ │ │ │ a listening port. If it hasn't, this function will return false, and then you │ │ │ │ │ can set a new _s_e_t_t_i_n_g_s___p_a_c_k_:_:_l_i_s_t_e_n___i_n_t_e_r_f_a_c_e_s to try another interface and │ │ │ │ │ port to bind to. │ │ │ │ │ listen_port() returns the port we ended up listening on. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** ggeett__ppeeeerr__ccllaassss__ffiilltteerr(()) sseett__ppeeeerr__ccllaassss__ffiilltteerr(()) ********** │ │ │ │ │ +********** sseett__ppeeeerr__ccllaassss__ffiilltteerr(()) ggeett__ppeeeerr__ccllaassss__ffiilltteerr(()) ********** │ │ │ │ │ ip_filter ggeett__ppeeeerr__ccllaassss__ffiilltteerr () const; │ │ │ │ │ void sseett__ppeeeerr__ccllaassss__ffiilltteerr (ip_filter const& f); │ │ │ │ │ Sets the peer class filter for this _s_e_s_s_i_o_n. All new peer connections will take │ │ │ │ │ this into account and be added to the peer classes specified by this filter, │ │ │ │ │ based on the peer's IP address. │ │ │ │ │ The ip-filter essentially maps an IP -> uint32. Each bit in that 32 bit integer │ │ │ │ │ represents a peer class. The least significant bit represents class 0, the next │ │ │ │ │ @@ -653,16 +653,16 @@ │ │ │ │ │ removed from a peer as a result of this call, peer classes are only added. │ │ │ │ │ The peer_class argument cannot be greater than 31. The bitmasks representing │ │ │ │ │ peer classes in the peer_class_filter are 32 bits. │ │ │ │ │ The get_peer_class_filter() function returns the current filter. │ │ │ │ │ For more information, see _p_e_e_r_ _c_l_a_s_s_e_s. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** sseett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr(()) ggeett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr(()) ********** │ │ │ │ │ -peer_class_type_filter ggeett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr () const; │ │ │ │ │ void sseett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr (peer_class_type_filter const& f); │ │ │ │ │ +peer_class_type_filter ggeett__ppeeeerr__ccllaassss__ttyyppee__ffiilltteerr () const; │ │ │ │ │ Sets and gets the ppeeeerr ccllaassss ttyyppee ffiilltteerr. This is controls automatic peer class │ │ │ │ │ assignments to peers based on what kind of socket it is. │ │ │ │ │ It does not only support assigning peer classes, it also supports removing peer │ │ │ │ │ classes based on socket type. │ │ │ │ │ The order of these rules being applied are: │ │ │ │ │ 1. peer-class IP filter │ │ │ │ │ 2. peer-class type filter, removing classes │ │ │ │ │ @@ -731,25 +731,25 @@ │ │ │ │ │ Note that when a queued or downloading torrent is removed, its position in the │ │ │ │ │ download queue is vacated and every subsequent torrent in the queue has their │ │ │ │ │ queue positions updated. This can potentially cause a large state_update to be │ │ │ │ │ posted. When removing all torrents, it is advised to remove them from the back │ │ │ │ │ of the queue, to minimize the shifting. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ ********** aappppllyy__sseettttiinnggss(()) ggeett__sseettttiinnggss(()) ********** │ │ │ │ │ +void aappppllyy__sseettttiinnggss (settings_pack&&); │ │ │ │ │ settings_pack ggeett__sseettttiinnggss () const; │ │ │ │ │ void aappppllyy__sseettttiinnggss (settings_pack const&); │ │ │ │ │ -void aappppllyy__sseettttiinnggss (settings_pack&&); │ │ │ │ │ Applies the settings specified by the _s_e_t_t_i_n_g_s___p_a_c_k s. This is an asynchronous │ │ │ │ │ operation that will return immediately and actually apply the settings to the │ │ │ │ │ main thread of libtorrent some time later. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -********** wwaaiitt__ffoorr__aalleerrtt(()) ppoopp__aalleerrttss(()) sseett__aalleerrtt__nnoottiiffyy(()) ********** │ │ │ │ │ +********** wwaaiitt__ffoorr__aalleerrtt(()) sseett__aalleerrtt__nnoottiiffyy(()) ppoopp__aalleerrttss(()) ********** │ │ │ │ │ void ppoopp__aalleerrttss (std::vector* alerts); │ │ │ │ │ -alert* wwaaiitt__ffoorr__aalleerrtt (time_duration max_wait); │ │ │ │ │ void sseett__aalleerrtt__nnoottiiffyy (std::function const& fun); │ │ │ │ │ +alert* wwaaiitt__ffoorr__aalleerrtt (time_duration max_wait); │ │ │ │ │ Alerts is the main mechanism for libtorrent to report errors and events. │ │ │ │ │ pop_alerts fills in the vector passed to it with pointers to new alerts. The │ │ │ │ │ _s_e_s_s_i_o_n still owns these alerts and they will stay valid until the next time │ │ │ │ │ pop_alerts is called. You may not delete the _a_l_e_r_t objects. │ │ │ │ │ It is safe to call pop_alerts from multiple different threads, as long as the │ │ │ │ │ alerts themselves are not accessed once another thread calls pop_alerts. Doing │ │ │ │ │ this requires manual synchronization between the popping threads. │ │ │ │ │ @@ -845,25 +845,25 @@ │ │ │ │ │ protocols used by _a_d_d___p_o_r_t___m_a_p_p_i_n_g_(_) │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ reopen_map_ports │ │ │ │ │ This option indicates if the ports are mapped using natpmp and upnp. If │ │ │ │ │ mapping was already made, they are deleted and added again. This only │ │ │ │ │ works if natpmp and/or upnp are configured to be enable. │ │ │ │ │ [_r_e_p_o_r_t_ _i_s_s_u_e] │ │ │ │ │ -************ rreeaadd__sseessssiioonn__ppaarraammss(()) wwrriittee__sseessssiioonn__ppaarraammss(()) wwrriittee__sseessssiioonn__ppaarraammss__bbuuff(()) │ │ │ │ │ +************ wwrriittee__sseessssiioonn__ppaarraammss__bbuuff(()) rreeaadd__sseessssiioonn__ppaarraammss(()) wwrriittee__sseessssiioonn__ppaarraammss(()) │ │ │ │ │ ************ │ │ │ │ │ Declared in "_l_i_b_t_o_r_r_e_n_t_/_s_e_s_s_i_o_n___p_a_r_a_m_s_._h_p_p" │ │ │ │ │ -session_params rreeaadd__sseessssiioonn__ppaarraammss (bdecode_node const& e │ │ │ │ │ +std::vector wwrriittee__sseessssiioonn__ppaarraammss__bbuuff (session_params const& sp │ │ │ │ │ , save_state_flags_t flags = save_state_flags_t::all()); │ │ │ │ │ entry wwrriittee__sseessssiioonn__ppaarraammss (session_params const& sp │ │ │ │ │ , save_state_flags_t flags = save_state_flags_t::all()); │ │ │ │ │ -std::vector wwrriittee__sseessssiioonn__ppaarraammss__bbuuff (session_params const& sp │ │ │ │ │ - , save_state_flags_t flags = save_state_flags_t::all()); │ │ │ │ │ session_params rreeaadd__sseessssiioonn__ppaarraammss (span buf │ │ │ │ │ , save_state_flags_t flags = save_state_flags_t::all()); │ │ │ │ │ +session_params rreeaadd__sseessssiioonn__ppaarraammss (bdecode_node const& e │ │ │ │ │ + , save_state_flags_t flags = save_state_flags_t::all()); │ │ │ │ │ These functions serialize and de-serialize a session_params object to and from │ │ │ │ │ bencoded form. The _s_e_s_s_i_o_n___p_a_r_a_m_s object is used to initialize a new _s_e_s_s_i_o_n │ │ │ │ │ using the state from a previous one (or by programmatically configure the │ │ │ │ │ _s_e_s_s_i_o_n up-front). The flags parameter can be used to only save and load │ │ │ │ │ certain aspects of the session's state. The _buf suffix indicates the function │ │ │ │ │ operates on buffer rather than the bencoded structure. The torrents in a │ │ │ │ │ _s_e_s_s_i_o_n are not part of the _s_e_s_s_i_o_n___p_a_r_a_m_s state, they have to be restored │ │ │ ├── ./usr/share/doc/libtorrent-rasterbar-doc/html/reference-Settings.html │ │ │ │ @@ -33,31 +33,31 @@ │ │ │ │

      Table of contents

      │ │ │ │ │ │ │ │
      │ │ │ │

      You have some control over session configuration through the session::apply_settings() │ │ │ │ member function. To change one or more configuration options, create a settings_pack │ │ │ │ object and fill it with the settings to be set and pass it in to session::apply_settings().

      │ │ │ │

      The settings_pack object is a collection of settings updates that are applied │ │ │ │ to the session when passed to session::apply_settings(). It's empty when │ │ │ │ @@ -4598,24 +4598,24 @@ │ │ │ │

      │ │ │ │
      │ │ │ │  struct settings_pack final : settings_interface
      │ │ │ │  {
      │ │ │ │     friend  void apply_pack_impl (settings_pack const*
      │ │ │ │        , aux::session_settings_single_thread&
      │ │ │ │        , std::vector<void(aux::session_impl::*)()>*);
      │ │ │ │ -   void set_int (int name, int val) override;
      │ │ │ │     void set_int (int name, flags::bitfield_flag<Type, Tag> const val);
      │ │ │ │ +   void set_int (int name, int val) override;
      │ │ │ │     void set_bool (int name, bool val) override;
      │ │ │ │     void set_str (int name, std::string val) override;
      │ │ │ │     bool has_val (int name) const override;
      │ │ │ │     void clear ();
      │ │ │ │     void clear (int name);
      │ │ │ │ +   bool get_bool (int name) const override;
      │ │ │ │     std::string const& get_str (int name) const override;
      │ │ │ │     int get_int (int name) const override;
      │ │ │ │ -   bool get_bool (int name) const override;
      │ │ │ │     void for_each (Fun&& f) const;
      │ │ │ │  
      │ │ │ │     enum type_bases
      │ │ │ │     {
      │ │ │ │        string_type_base,
      │ │ │ │        int_type_base,
      │ │ │ │        bool_type_base,
      │ │ │ │ @@ -4690,16 +4690,16 @@
      │ │ │ │  };
      │ │ │ │  
      │ │ │ │ │ │ │ │ │ │ │ │ [report issue]
      │ │ │ │

      set_int() set_bool() set_str()

      │ │ │ │
      │ │ │ │ -void set_int (int name, int val) override;
      │ │ │ │  void set_int (int name, flags::bitfield_flag<Type, Tag> const val);
      │ │ │ │ +void set_int (int name, int val) override;
      │ │ │ │  void set_bool (int name, bool val) override;
      │ │ │ │  void set_str (int name, std::string val) override;
      │ │ │ │  
      │ │ │ │

      set a configuration option in the settings_pack. name is one of │ │ │ │ the enum values from string_types, int_types or bool_types. They must │ │ │ │ match the respective type of the set_* function.

      │ │ │ │ [report issue]
      │ │ │ │ @@ -4721,23 +4721,23 @@ │ │ │ │ [report issue]
      │ │ │ │
      │ │ │ │

      clear()

      │ │ │ │
      │ │ │ │  void clear (int name);
      │ │ │ │  
      │ │ │ │

      clear a specific setting from the pack

      │ │ │ │ + │ │ │ │ │ │ │ │ - │ │ │ │ -[report issue]
      │ │ │ │ -
      │ │ │ │ -

      get_str() get_bool() get_int()

      │ │ │ │ +[report issue]
      │ │ │ │ +
      │ │ │ │ +

      get_int() get_str() get_bool()

      │ │ │ │
      │ │ │ │ +bool get_bool (int name) const override;
      │ │ │ │  std::string const& get_str (int name) const override;
      │ │ │ │  int get_int (int name) const override;
      │ │ │ │ -bool get_bool (int name) const override;
      │ │ │ │  
      │ │ │ │

      queries the current configuration option from the settings_pack. │ │ │ │ name is one of the enumeration values from string_types, int_types │ │ │ │ or bool_types. The enum value must match the type of the get_* │ │ │ │ function. If the specified setting field has not been set, the default │ │ │ │ value is returned.

      │ │ │ │ [report issue]
      │ │ │ │ @@ -5096,19 +5096,38 @@ │ │ │ │ http_pw │ │ │ │ 5 │ │ │ │ The server is assumed to be an HTTP proxy that requires user │ │ │ │ authorization. The username and password will be sent to the proxy. │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ - │ │ │ │ -[report issue]
      │ │ │ │ + │ │ │ │ +[report issue]
    │ │ │ │
    │ │ │ │ -
    │ │ │ │ -

    min_memory_usage() high_performance_seed()

    │ │ │ │ +
    │ │ │ │ +

    name_for_setting() setting_by_name()

    │ │ │ │ +

    Declared in "libtorrent/settings_pack.hpp"

    │ │ │ │ +
    │ │ │ │ +char const* name_for_setting (int s);
    │ │ │ │ +int setting_by_name (string_view name);
    │ │ │ │ +
    │ │ │ │ +

    converts a setting integer (from the enums string_types, int_types or │ │ │ │ +bool_types) to a string, and vice versa.

    │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    default_settings()

    │ │ │ │ +

    Declared in "libtorrent/settings_pack.hpp"

    │ │ │ │ +
    │ │ │ │ +settings_pack default_settings ();
    │ │ │ │ +
    │ │ │ │ +

    returns a settings_pack with every setting set to its default value

    │ │ │ │ + │ │ │ │ +[report issue]
    │ │ │ │ +
    │ │ │ │ +

    high_performance_seed() min_memory_usage()

    │ │ │ │

    Declared in "libtorrent/session.hpp"

    │ │ │ │
    │ │ │ │  settings_pack min_memory_usage ();
    │ │ │ │  settings_pack high_performance_seed ();
    │ │ │ │  
    │ │ │ │

    The default values of the session settings are set for a regular │ │ │ │ bittorrent client running on a desktop system. There are functions that │ │ │ │ @@ -5183,33 +5202,14 @@ │ │ │ │ Tribler │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │

    There's an informal directory of client id's here.

    │ │ │ │

    The major, minor, revision and tag parameters are used to │ │ │ │ identify the version of your client.

    │ │ │ │ - │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    setting_by_name() name_for_setting()

    │ │ │ │ -

    Declared in "libtorrent/settings_pack.hpp"

    │ │ │ │ -
    │ │ │ │ -int setting_by_name (string_view name);
    │ │ │ │ -char const* name_for_setting (int s);
    │ │ │ │ -
    │ │ │ │ -

    converts a setting integer (from the enums string_types, int_types or │ │ │ │ -bool_types) to a string, and vice versa.

    │ │ │ │ -[report issue]
    │ │ │ │ -
    │ │ │ │ -

    default_settings()

    │ │ │ │ -

    Declared in "libtorrent/settings_pack.hpp"

    │ │ │ │ -
    │ │ │ │ -settings_pack default_settings ();
    │ │ │ │ -
    │ │ │ │ -

    returns a settings_pack with every setting set to its default value

    │ │ │ │
    │ │ │ │ │ │ │ │
    │ │ │ │ │ │ │ │
    │ │ │ │
    │ │ │ │ utp_socket_impl* impl = nullptr; │ │ │ │ + transport ssl = transport::plaintext; │ │ │ │ +#if TORRENT_USE_SSL │ │ │ │ + if (boost::get<ssl_stream<utp_stream>>(&s) != nullptr) │ │ │ │ + { │ │ │ │ + impl = boost::get<ssl_stream<utp_stream>>(s).next_layer().get_impl(); │ │ │ │ + ssl = transport::ssl; │ │ │ │ + } │ │ │ │ + else │ │ │ │ +#endif │ │ │ │ + impl = boost::get<utp_stream>(s).get_impl(); │ │ │ │ │ │ │ │ - // returns whether this add_torrent_params object has "resume-data", i.e. │ │ │ │ - // information about which pieces we have. │ │ │ │ - bool contains_resume_data(add_torrent_params const& atp) │ │ │ │ + std::vector<std::shared_ptr<listen_socket_t>> with_gateways; │ │ │ │ + std::shared_ptr<listen_socket_t> match; │ │ │ │ + for (auto& ls : m_listen_sockets) │ │ │ │ + { │ │ │ │ + // this is almost, but not quite, like can_route() │ │ │ │ + if (!(ls->flags & listen_socket_t::proxy) │ │ │ │ + && is_v4(ls->local_endpoint) != remote_address.is_v4()) │ │ │ │ + continue; │ │ │ │ + if (ls->ssl != ssl) continue; │ │ │ │ + if (!(ls->flags & listen_socket_t::local_network)) │ │ │ │ + with_gateways.push_back(ls); │ │ │ │ + │ │ │ │ + if (ls->flags & listen_socket_t::proxy │ │ │ │ + || match_addr_mask(ls->local_endpoint.address(), remote_address, ls->netmask)) │ │ │ │ + { │ │ │ │ + // is this better than the previous match? │ │ │ │ + match = ls; │ │ │ │ + } │ │ │ │ +relevance 0../src/session_impl.cpp:5880refactor, move the storage to dht_tracker

    refactor, move the storage to dht_tracker

    ../src/session_impl.cpp:5880

    #ifndef TORRENT_DISABLE_LOGGING
    │ │ │ │ +			session_log("not starting DHT, outstanding router lookups: %d"
    │ │ │ │ +				, m_outstanding_router_lookups);
    │ │ │ │ +#endif
    │ │ │ │ +			return;
    │ │ │ │ +		}
    │ │ │ │ +
    │ │ │ │ +		if (m_abort)
    │ │ │ │ +		{
    │ │ │ │ +#ifndef TORRENT_DISABLE_LOGGING
    │ │ │ │ +			session_log("not starting DHT, aborting");
    │ │ │ │ +#endif
    │ │ │ │ +			return;
    │ │ │ │ +		}
    │ │ │ │ +
    │ │ │ │ +#ifndef TORRENT_DISABLE_LOGGING
    │ │ │ │ +		session_log("starting DHT, running: %s, router lookups: %d"
    │ │ │ │ +			, m_dht ? "true" : "false", m_outstanding_router_lookups);
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +
    m_dht_storage = m_dht_storage_constructor(m_settings); │ │ │ │ +
    m_dht = std::make_shared<dht::dht_tracker>( │ │ │ │ + static_cast<dht::dht_observer*>(this) │ │ │ │ + , m_io_context │ │ │ │ + , [this](aux::listen_socket_handle const& sock │ │ │ │ + , udp::endpoint const& ep │ │ │ │ + , span<char const> p │ │ │ │ + , error_code& ec │ │ │ │ + , udp_send_flags_t const flags) │ │ │ │ + { send_udp_packet_listen(sock, ep, p, ec, flags); } │ │ │ │ + , m_settings │ │ │ │ + , m_stats_counters │ │ │ │ + , *m_dht_storage │ │ │ │ + , std::move(m_dht_state)); │ │ │ │ + │ │ │ │ + for (auto& s : m_listen_sockets) │ │ │ │ + { │ │ │ │ + if (s->ssl != transport::ssl │ │ │ │ + && !(s->flags & listen_socket_t::local_network)) │ │ │ │ + { │ │ │ │ + m_dht->new_socket(s); │ │ │ │ + } │ │ │ │ + } │ │ │ │ + │ │ │ │ + for (auto const& n : m_dht_router_nodes) │ │ │ │ + { │ │ │ │ + m_dht->add_router_node(n); │ │ │ │ + } │ │ │ │ + │ │ │ │ + for (auto const& n : m_dht_nodes) │ │ │ │ + { │ │ │ │ +
    relevance 0../src/session_impl.cpp:6267asserts that no outstanding async operations are still in flight

    asserts that no outstanding async operations are still in flight

    ../src/session_impl.cpp:6267

    		if (!m_dht) return;
    │ │ │ │ +		m_dht->direct_request(ep, e, std::bind(&on_direct_response, std::ref(m_alerts), userdata, _1));
    │ │ │ │ +	}
    │ │ │ │ +
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +	bool session_impl::is_listening() const
    │ │ │ │  	{
    │ │ │ │ -		return !atp.have_pieces.empty()
    │ │ │ │ -			|| (atp.flags & torrent_flags::seed_mode);
    │ │ │ │ +		return !m_listen_sockets.empty();
    │ │ │ │  	}
    │ │ │ │ -}
    │ │ │ │  
    │ │ │ │ -}
    │ │ │ │ +	session_impl::~session_impl()
    │ │ │ │ +	{
    │ │ │ │ +		// since we're destructing the session, no more alerts will make it out to
    │ │ │ │ +		// the user. So stop posting them now
    │ │ │ │ +		m_alerts.set_alert_mask({});
    │ │ │ │ +		m_alerts.set_notify_function({});
    │ │ │ │ +
    │ │ │ │ +		// this is not allowed to be the network thread!
    │ │ │ │ +//		TORRENT_ASSERT(is_not_thread());
    │ │ │ │ +
    │ │ │ │ +
    // this can happen if we end the io_context run loop with an exception │ │ │ │ + m_connections.clear(); │ │ │ │ + for (auto& t : m_torrents) │ │ │ │ + { │ │ │ │ + t->panic(); │ │ │ │ + t->abort(); │ │ │ │ + } │ │ │ │ + m_torrents.clear(); │ │ │ │ + │ │ │ │ + // this has probably been called already, but in case of sudden │ │ │ │ + // termination through an exception, it may not have been done │ │ │ │ + abort_stage2(); │ │ │ │ + │ │ │ │ +#if defined TORRENT_ASIO_DEBUGGING │ │ │ │ + FILE* f = fopen("wakeups.log", "w+"); │ │ │ │ + if (f != nullptr) │ │ │ │ + { │ │ │ │ + time_point m = min_time(); │ │ │ │ + if (!_wakeups.empty()) m = _wakeups[0].timestamp; │ │ │ │ + time_point prev = m; │ │ │ │ + std::uint64_t prev_csw = 0; │ │ │ │ + if (!_wakeups.empty()) prev_csw = _wakeups[0].context_switches; │ │ │ │ + std::fprintf(f, "abs. time\trel. time\tctx switch\tidle-wakeup\toperation\n"); │ │ │ │ + for (wakeup_t const& w : _wakeups) │ │ │ │ + { │ │ │ │ + bool const idle_wakeup = w.context_switches > prev_csw; │ │ │ │ + std::fprintf(f, "%" PRId64 "\t%" PRId64 "\t%" PRId64 "\t%c\t%s\n" │ │ │ │ + , total_microseconds(w.timestamp - m) │ │ │ │ + , total_microseconds(w.timestamp - prev) │ │ │ │ + , w.context_switches │ │ │ │ +
    relevance 0../src/packet_buffer.cpp:157use compare_less_wrap for this comparison as well

    use compare_less_wrap for this comparison as well

    ../src/packet_buffer.cpp:157

    	{
    │ │ │ │ +		INVARIANT_CHECK;
    │ │ │ │ +		TORRENT_ASSERT_VAL(size <= 0xffff, size);
    │ │ │ │ +		std::uint32_t new_size = m_capacity == 0 ? 16 : m_capacity;
    │ │ │ │ +
    │ │ │ │ +		while (new_size < size)
    │ │ │ │ +			new_size <<= 1;
    │ │ │ │ +
    │ │ │ │ +		aux::unique_ptr<packet_ptr[], index_type> new_storage(new packet_ptr[new_size]);
    │ │ │ │ +
    │ │ │ │ +		for (index_type i = m_first; i < (m_first + m_capacity); ++i)
    │ │ │ │ +			new_storage[i & (new_size - 1)] = std::move(m_storage[i & (m_capacity - 1)]);
    │ │ │ │ +
    │ │ │ │ +		m_storage = std::move(new_storage);
    │ │ │ │ +		m_capacity = new_size;
    │ │ │ │ +	}
    │ │ │ │ +
    │ │ │ │ +	packet_ptr packet_buffer::remove(index_type idx)
    │ │ │ │ +	{
    │ │ │ │ +		INVARIANT_CHECK;
    │ │ │ │ +
    if (idx >= m_first + m_capacity) │ │ │ │ +
    return packet_ptr(); │ │ │ │ + │ │ │ │ + if (compare_less_wrap(idx, m_first, 0xffff)) │ │ │ │ + return packet_ptr(); │ │ │ │ + │ │ │ │ + std::size_t const mask = m_capacity - 1; │ │ │ │ + packet_ptr old_value = std::move(m_storage[idx & mask]); │ │ │ │ + m_storage[idx & mask].reset(); │ │ │ │ + │ │ │ │ + if (old_value) │ │ │ │ + { │ │ │ │ + --m_size; │ │ │ │ + if (m_size == 0) m_last = m_first; │ │ │ │ + } │ │ │ │ + │ │ │ │ + if (idx == m_first && m_size != 0) │ │ │ │ + { │ │ │ │ + ++m_first; │ │ │ │ + for (index_type i = 0; i < m_capacity; ++i, ++m_first) │ │ │ │ + if (m_storage[m_first & mask]) break; │ │ │ │ + m_first &= 0xffff; │ │ │ │ + } │ │ │ │ + │ │ │ │ + if (((idx + 1) & 0xffff) == m_last && m_size != 0) │ │ │ │ + { │ │ │ │ + --m_last; │ │ │ │ + for (index_type i = 0; i < m_capacity; ++i, --m_last) │ │ │ │ + if (m_storage[m_last & mask]) break; │ │ │ │ + ++m_last; │ │ │ │ + m_last &= 0xffff; │ │ │ │
    relevance 0../src/kademlia/node.cpp:1177keep the returned value to pass as a limit to write_nodes_entries when implemented

    keep the returned value to pass as a limit │ │ │ │ to write_nodes_entries when implemented

    ../src/kademlia/node.cpp:1177

    		}
    │ │ │ │  	}
    │ │ │ │  	else if (query == "sample_infohashes")
    │ │ │ │  	{
    │ │ │ │  		static key_desc_t const msg_desc[] = {
    │ │ │ │  			{"target", bdecode_node::string_t, 20, 0},
    │ │ │ │ @@ -9997,15 +9997,157 @@
    │ │ │ │  		std::vector<node_entry> const n = wanted_node->m_table.find_node(info_hash, {});
    │ │ │ │  		r[wanted_node->protocol_nodes_key()] = write_nodes_entry(n);
    │ │ │ │  	}
    │ │ │ │  }
    │ │ │ │  
    │ │ │ │  node::protocol_descriptor const& node::map_protocol_to_descriptor(udp const protocol)
    │ │ │ │  {
    │ │ │ │ -
    relevance 0../src/kademlia/put_data.cpp:92what if o is not an instance of put_data_observer? This need to be redesigned for better type safety.

    what if o is not an instance of put_data_observer? This need to be │ │ │ │ +relevance 0../src/kademlia/routing_table.cpp:289This is temporary. For now, only report the largest routing table (of potentially multiple ones, for multi-homed systems) in next major version, break the ABI and support reporting all of them in the dht_stats_alert

    This is temporary. For now, only report the largest routing table │ │ │ │ +(of potentially multiple ones, for multi-homed systems) │ │ │ │ +in next major version, break the ABI and support reporting all of them in │ │ │ │ +the dht_stats_alert

    ../src/kademlia/routing_table.cpp:289

    	, m_bucket_size(bucket_size)
    │ │ │ │ +{
    │ │ │ │ +	// bucket sizes must be a power of 2
    │ │ │ │ +	TORRENT_ASSERT_VAL(((bucket_size - 1) & bucket_size) == 0, bucket_size);
    │ │ │ │ +	TORRENT_UNUSED(log);
    │ │ │ │ +	m_buckets.reserve(30);
    │ │ │ │ +}
    │ │ │ │ +
    │ │ │ │ +int routing_table::bucket_limit(int bucket) const
    │ │ │ │ +{
    │ │ │ │ +	if (!m_settings.get_bool(settings_pack::dht_extended_routing_table)) return m_bucket_size;
    │ │ │ │ +
    │ │ │ │ +	static const aux::array<int, 4> size_exceptions{{{16, 8, 4, 2}}};
    │ │ │ │ +	if (bucket < size_exceptions.end_index())
    │ │ │ │ +		return m_bucket_size * size_exceptions[bucket];
    │ │ │ │ +	return m_bucket_size;
    │ │ │ │ +}
    │ │ │ │ +
    │ │ │ │ +void routing_table::status(std::vector<dht_routing_bucket>& s) const
    │ │ │ │ +{
    │ │ │ │ +
    if (s.size() > m_buckets.size()) return; │ │ │ │ +
    s.clear(); │ │ │ │ + for (auto const& i : m_buckets) │ │ │ │ + { │ │ │ │ + dht_routing_bucket b; │ │ │ │ + b.num_nodes = int(i.live_nodes.size()); │ │ │ │ + b.num_replacements = int(i.replacements.size()); │ │ │ │ + s.push_back(b); │ │ │ │ + } │ │ │ │ +} │ │ │ │ + │ │ │ │ +#if TORRENT_ABI_VERSION == 1 │ │ │ │ +
    relevance 0../src/kademlia/routing_table.cpp:314arvidn note when it's across IPv4 and IPv6, adding (dht_global_nodes) would make sense. in the future though, where we may have one DHT node per external interface (which may be multiple of the same address family), then it becomes a bit trickier

    arvidn note │ │ │ │ +when it's across IPv4 and IPv6, adding (dht_global_nodes) would │ │ │ │ +make sense. in the future though, where we may have one DHT node │ │ │ │ +per external interface (which may be multiple of the same address │ │ │ │ +family), then it becomes a bit trickier

    ../src/kademlia/routing_table.cpp:314

    	if (s.size() > m_buckets.size()) return;
    │ │ │ │ +	s.clear();
    │ │ │ │ +	for (auto const& i : m_buckets)
    │ │ │ │ +	{
    │ │ │ │ +		dht_routing_bucket b;
    │ │ │ │ +		b.num_nodes = int(i.live_nodes.size());
    │ │ │ │ +		b.num_replacements = int(i.replacements.size());
    │ │ │ │ +		s.push_back(b);
    │ │ │ │ +	}
    │ │ │ │ +}
    │ │ │ │ +
    │ │ │ │ +#if TORRENT_ABI_VERSION == 1
    │ │ │ │ +void routing_table::status(session_status& s) const
    │ │ │ │ +{
    │ │ │ │ +	int dht_nodes;
    │ │ │ │ +	int dht_node_cache;
    │ │ │ │ +	int ignore;
    │ │ │ │ +	std::tie(dht_nodes, dht_node_cache, ignore) = size();
    │ │ │ │ +	s.dht_nodes += dht_nodes;
    │ │ │ │ +	s.dht_node_cache += dht_node_cache;
    │ │ │ │ +
    s.dht_global_nodes += num_global_nodes(); │ │ │ │ +
    │ │ │ │ + for (auto const& i : m_buckets) │ │ │ │ + { │ │ │ │ + dht_routing_bucket b; │ │ │ │ + b.num_nodes = int(i.live_nodes.size()); │ │ │ │ + b.num_replacements = int(i.replacements.size()); │ │ │ │ +#if TORRENT_ABI_VERSION == 1 │ │ │ │ + b.last_active = 0; │ │ │ │ +#endif │ │ │ │ + s.dht_routing_table.push_back(b); │ │ │ │ + } │ │ │ │ +} │ │ │ │ +#endif │ │ │ │ + │ │ │ │ +std::tuple<int, int, int> routing_table::size() const │ │ │ │ +{ │ │ │ │ + int nodes = 0; │ │ │ │ + int replacements = 0; │ │ │ │ + int confirmed = 0; │ │ │ │ + for (auto const& i : m_buckets) │ │ │ │ + { │ │ │ │ + nodes += int(i.live_nodes.size()); │ │ │ │ + confirmed += static_cast<int>(std::count_if(i.live_nodes.begin(), i.live_nodes.end() │ │ │ │ + , [](node_entry const& k) { return k.confirmed(); } )); │ │ │ │ + │ │ │ │ + replacements += int(i.replacements.size()); │ │ │ │ + } │ │ │ │ + return std::make_tuple(nodes, replacements, confirmed); │ │ │ │ +} │ │ │ │ + │ │ │ │ +
    relevance 0../src/kademlia/routing_table.cpp:518this need to take bucket "prefix" into account. It should be unified with add_node_impl()

    this need to take bucket "prefix" into account. It should be unified │ │ │ │ +with add_node_impl()

    ../src/kademlia/routing_table.cpp:518

    {
    │ │ │ │ +	for (auto i = m_buckets.begin() , end(m_buckets.end()); i != end; ++i)
    │ │ │ │ +	{
    │ │ │ │ +		for (auto j = i->replacements.begin(); j != i->replacements.end(); ++j)
    │ │ │ │ +		{
    │ │ │ │ +			if (j->addr() != ep.address()) continue;
    │ │ │ │ +			if (j->port() != ep.port()) continue;
    │ │ │ │ +			return std::make_tuple(&*j, i, &i->replacements);
    │ │ │ │ +		}
    │ │ │ │ +		for (auto j = i->live_nodes.begin(); j != i->live_nodes.end(); ++j)
    │ │ │ │ +		{
    │ │ │ │ +			if (j->addr() != ep.address()) continue;
    │ │ │ │ +			if (j->port() != ep.port()) continue;
    │ │ │ │ +			return std::make_tuple(&*j, i, &i->live_nodes);
    │ │ │ │ +		}
    │ │ │ │ +	}
    │ │ │ │ +	return std::tuple<node_entry*, routing_table::table_t::iterator, bucket_t*>
    │ │ │ │ +	{nullptr, m_buckets.end(), nullptr};
    │ │ │ │ +}
    │ │ │ │ +
    │ │ │ │ +
    void routing_table::fill_from_replacements(table_t::iterator bucket) │ │ │ │ +
    { │ │ │ │ + bucket_t& b = bucket->live_nodes; │ │ │ │ + bucket_t& rb = bucket->replacements; │ │ │ │ + int const bucket_size = bucket_limit(int(std::distance(m_buckets.begin(), bucket))); │ │ │ │ + │ │ │ │ + if (int(b.size()) >= bucket_size) return; │ │ │ │ + │ │ │ │ + // sort by RTT first, to find the node with the lowest │ │ │ │ + // RTT that is pinged │ │ │ │ + std::sort(rb.begin(), rb.end()); │ │ │ │ + │ │ │ │ + while (int(b.size()) < bucket_size && !rb.empty()) │ │ │ │ + { │ │ │ │ + auto j = std::find_if(rb.begin(), rb.end(), std::bind(&node_entry::pinged, _1)); │ │ │ │ + if (j == rb.end()) break; │ │ │ │ + b.push_back(*j); │ │ │ │ + rb.erase(j); │ │ │ │ + } │ │ │ │ +} │ │ │ │ + │ │ │ │ +void routing_table::prune_empty_bucket() │ │ │ │ +{ │ │ │ │ + if (m_buckets.back().live_nodes.empty() │ │ │ │ + && m_buckets.back().replacements.empty()) │ │ │ │ + { │ │ │ │ + m_buckets.erase(m_buckets.end() - 1); │ │ │ │ + } │ │ │ │ +} │ │ │ │ + │ │ │ │ +void routing_table::remove_node(node_entry* n, bucket_t* b) │ │ │ │ +
    relevance 0../src/kademlia/put_data.cpp:92what if o is not an instance of put_data_observer? This need to be redesigned for better type safety.

    what if o is not an instance of put_data_observer? This need to be │ │ │ │ redesigned for better type safety.

    ../src/kademlia/put_data.cpp:92

    	}
    │ │ │ │  }
    │ │ │ │  
    │ │ │ │  void put_data::done()
    │ │ │ │  {
    │ │ │ │  	m_done = true;
    │ │ │ │  
    │ │ │ │ @@ -10043,15 +10185,15 @@
    │ │ │ │  
    │ │ │ │  	m_node.stats_counters().inc_stats_counter(counters::dht_put_out);
    │ │ │ │  
    │ │ │ │  	return m_node.m_rpc.invoke(e, o->target_ep(), o);
    │ │ │ │  }
    │ │ │ │  
    │ │ │ │  } } // namespace libtorrent::dht
    │ │ │ │ -
    relevance 0../src/kademlia/node_id.cpp:66it's a little bit weird to return 159 - leading zeroes. It should probably be 160 - leading zeroes, but all other code in here is tuned to this expectation now, and it doesn't really matter (other than complexity)

    it's a little bit weird to return 159 - leading zeroes. It should │ │ │ │ +relevance 0../src/kademlia/node_id.cpp:66it's a little bit weird to return 159 - leading zeroes. It should probably be 160 - leading zeroes, but all other code in here is tuned to this expectation now, and it doesn't really matter (other than complexity)

    it's a little bit weird to return 159 - leading zeroes. It should │ │ │ │ probably be 160 - leading zeroes, but all other code in here is tuned to │ │ │ │ this expectation now, and it doesn't really matter (other than complexity)

    ../src/kademlia/node_id.cpp:66

    │ │ │ │  // returns the distance between the two nodes
    │ │ │ │  // using the kademlia XOR-metric
    │ │ │ │  node_id distance(node_id const& n1, node_id const& n2)
    │ │ │ │  {
    │ │ │ │  	return n1 ^ n2;
    │ │ │ │ @@ -10096,66 +10238,15 @@
    │ │ │ │  
    │ │ │ │  	address_v4::bytes_type b4{};
    │ │ │ │  	address_v6::bytes_type b6{};
    │ │ │ │  	if (ip_.is_v6())
    │ │ │ │  	{
    │ │ │ │  		b6 = ip_.to_v6().to_bytes();
    │ │ │ │  		ip = b6.data();
    │ │ │ │ -
    relevance 0../src/kademlia/dht_tracker.cpp:317pick the closest node rather than the first

    pick the closest node rather than the first

    ../src/kademlia/dht_tracker.cpp:317

    │ │ │ │ -#ifndef TORRENT_DISABLE_LOGGING
    │ │ │ │ -		m_log->log(dht_logger::tracker, "*** new write key*** %d nodes"
    │ │ │ │ -			, int(m_nodes.size()));
    │ │ │ │ -#endif
    │ │ │ │ -	}
    │ │ │ │ -
    │ │ │ │ -	void dht_tracker::update_storage_node_ids()
    │ │ │ │ -	{
    │ │ │ │ -		std::vector<sha1_hash> ids;
    │ │ │ │ -		for (auto& n : m_nodes)
    │ │ │ │ -			ids.push_back(n.second.dht.nid());
    │ │ │ │ -		m_storage.update_node_ids(ids);
    │ │ │ │ -	}
    │ │ │ │ -
    │ │ │ │ -	node* dht_tracker::get_node(node_id const& id, std::string const& family_name)
    │ │ │ │ -	{
    │ │ │ │ -		TORRENT_UNUSED(id);
    │ │ │ │ -		for (auto& n : m_nodes)
    │ │ │ │ -		{
    │ │ │ │ -
    if (n.second.dht.protocol_family_name() == family_name) │ │ │ │ -
    return &n.second.dht; │ │ │ │ - } │ │ │ │ - │ │ │ │ - return nullptr; │ │ │ │ - } │ │ │ │ - │ │ │ │ - void dht_tracker::get_peers(sha1_hash const& ih │ │ │ │ - , std::function<void(std::vector<tcp::endpoint> const&)> f) │ │ │ │ - { │ │ │ │ - for (auto& n : m_nodes) │ │ │ │ - n.second.dht.get_peers(ih, f, {}, {}); │ │ │ │ - } │ │ │ │ - │ │ │ │ - void dht_tracker::announce(sha1_hash const& ih, int listen_port │ │ │ │ - , announce_flags_t const flags │ │ │ │ - , std::function<void(std::vector<tcp::endpoint> const&)> f) │ │ │ │ - { │ │ │ │ - for (auto& n : m_nodes) │ │ │ │ - n.second.dht.announce(ih, listen_port, flags, f); │ │ │ │ - } │ │ │ │ - │ │ │ │ - void dht_tracker::sample_infohashes(udp::endpoint const& ep, sha1_hash const& target │ │ │ │ - , std::function<void(node_id │ │ │ │ - , time_duration │ │ │ │ - , int, std::vector<sha1_hash> │ │ │ │ - , std::vector<std::pair<sha1_hash, udp::endpoint>>)> f) │ │ │ │ - { │ │ │ │ - for (auto& n : m_nodes) │ │ │ │ - { │ │ │ │ - if (ep.protocol() != (n.first.get_external_address().is_v4() ? udp::v4() : udp::v6())) │ │ │ │ -
    relevance 0../src/kademlia/item.cpp:143implement ctor for entry from bdecode_node?

    implement ctor for entry from bdecode_node?

    ../src/kademlia/item.cpp:143

    	, secret_key const& sk)
    │ │ │ │ +
    relevance 0../src/kademlia/item.cpp:143implement ctor for entry from bdecode_node?

    implement ctor for entry from bdecode_node?

    ../src/kademlia/item.cpp:143

    	, secret_key const& sk)
    │ │ │ │  {
    │ │ │ │  	char str[1200];
    │ │ │ │  	int const len = canonical_string(v, seq, salt, str);
    │ │ │ │  
    │ │ │ │  	return ed25519_sign({str, len}, pk, sk);
    │ │ │ │  }
    │ │ │ │  
    │ │ │ │ @@ -10198,156 +10289,65 @@
    │ │ │ │  	m_pk = pk;
    │ │ │ │  	m_seq = seq;
    │ │ │ │  	m_mutable = true;
    │ │ │ │  	m_value = std::move(v);
    │ │ │ │  }
    │ │ │ │  
    │ │ │ │  void item::assign(bdecode_node const& v)
    │ │ │ │ -
    relevance 0../src/kademlia/routing_table.cpp:289This is temporary. For now, only report the largest routing table (of potentially multiple ones, for multi-homed systems) in next major version, break the ABI and support reporting all of them in the dht_stats_alert

    This is temporary. For now, only report the largest routing table │ │ │ │ -(of potentially multiple ones, for multi-homed systems) │ │ │ │ -in next major version, break the ABI and support reporting all of them in │ │ │ │ -the dht_stats_alert

    ../src/kademlia/routing_table.cpp:289

    	, m_bucket_size(bucket_size)
    │ │ │ │ -{
    │ │ │ │ -	// bucket sizes must be a power of 2
    │ │ │ │ -	TORRENT_ASSERT_VAL(((bucket_size - 1) & bucket_size) == 0, bucket_size);
    │ │ │ │ -	TORRENT_UNUSED(log);
    │ │ │ │ -	m_buckets.reserve(30);
    │ │ │ │ -}
    │ │ │ │ -
    │ │ │ │ -int routing_table::bucket_limit(int bucket) const
    │ │ │ │ -{
    │ │ │ │ -	if (!m_settings.get_bool(settings_pack::dht_extended_routing_table)) return m_bucket_size;
    │ │ │ │ -
    │ │ │ │ -	static const aux::array<int, 4> size_exceptions{{{16, 8, 4, 2}}};
    │ │ │ │ -	if (bucket < size_exceptions.end_index())
    │ │ │ │ -		return m_bucket_size * size_exceptions[bucket];
    │ │ │ │ -	return m_bucket_size;
    │ │ │ │ -}
    │ │ │ │ -
    │ │ │ │ -void routing_table::status(std::vector<dht_routing_bucket>& s) const
    │ │ │ │ -{
    │ │ │ │ -
    if (s.size() > m_buckets.size()) return; │ │ │ │ -
    s.clear(); │ │ │ │ - for (auto const& i : m_buckets) │ │ │ │ - { │ │ │ │ - dht_routing_bucket b; │ │ │ │ - b.num_nodes = int(i.live_nodes.size()); │ │ │ │ - b.num_replacements = int(i.replacements.size()); │ │ │ │ - s.push_back(b); │ │ │ │ - } │ │ │ │ -} │ │ │ │ - │ │ │ │ -#if TORRENT_ABI_VERSION == 1 │ │ │ │ -
    relevance 0../src/kademlia/routing_table.cpp:314arvidn note when it's across IPv4 and IPv6, adding (dht_global_nodes) would make sense. in the future though, where we may have one DHT node per external interface (which may be multiple of the same address family), then it becomes a bit trickier

    arvidn note │ │ │ │ -when it's across IPv4 and IPv6, adding (dht_global_nodes) would │ │ │ │ -make sense. in the future though, where we may have one DHT node │ │ │ │ -per external interface (which may be multiple of the same address │ │ │ │ -family), then it becomes a bit trickier

    ../src/kademlia/routing_table.cpp:314

    	if (s.size() > m_buckets.size()) return;
    │ │ │ │ -	s.clear();
    │ │ │ │ -	for (auto const& i : m_buckets)
    │ │ │ │ -	{
    │ │ │ │ -		dht_routing_bucket b;
    │ │ │ │ -		b.num_nodes = int(i.live_nodes.size());
    │ │ │ │ -		b.num_replacements = int(i.replacements.size());
    │ │ │ │ -		s.push_back(b);
    │ │ │ │ -	}
    │ │ │ │ -}
    │ │ │ │ -
    │ │ │ │ -#if TORRENT_ABI_VERSION == 1
    │ │ │ │ -void routing_table::status(session_status& s) const
    │ │ │ │ -{
    │ │ │ │ -	int dht_nodes;
    │ │ │ │ -	int dht_node_cache;
    │ │ │ │ -	int ignore;
    │ │ │ │ -	std::tie(dht_nodes, dht_node_cache, ignore) = size();
    │ │ │ │ -	s.dht_nodes += dht_nodes;
    │ │ │ │ -	s.dht_node_cache += dht_node_cache;
    │ │ │ │ -
    s.dht_global_nodes += num_global_nodes(); │ │ │ │ -
    │ │ │ │ - for (auto const& i : m_buckets) │ │ │ │ - { │ │ │ │ - dht_routing_bucket b; │ │ │ │ - b.num_nodes = int(i.live_nodes.size()); │ │ │ │ - b.num_replacements = int(i.replacements.size()); │ │ │ │ -#if TORRENT_ABI_VERSION == 1 │ │ │ │ - b.last_active = 0; │ │ │ │ +
    relevance 0../src/kademlia/dht_tracker.cpp:317pick the closest node rather than the first

    pick the closest node rather than the first

    ../src/kademlia/dht_tracker.cpp:317

    │ │ │ │ +#ifndef TORRENT_DISABLE_LOGGING
    │ │ │ │ +		m_log->log(dht_logger::tracker, "*** new write key*** %d nodes"
    │ │ │ │ +			, int(m_nodes.size()));
    │ │ │ │  #endif
    │ │ │ │ -		s.dht_routing_table.push_back(b);
    │ │ │ │  	}
    │ │ │ │ -}
    │ │ │ │ -#endif
    │ │ │ │  
    │ │ │ │ -std::tuple<int, int, int> routing_table::size() const
    │ │ │ │ -{
    │ │ │ │ -	int nodes = 0;
    │ │ │ │ -	int replacements = 0;
    │ │ │ │ -	int confirmed = 0;
    │ │ │ │ -	for (auto const& i : m_buckets)
    │ │ │ │ +	void dht_tracker::update_storage_node_ids()
    │ │ │ │  	{
    │ │ │ │ -		nodes += int(i.live_nodes.size());
    │ │ │ │ -		confirmed += static_cast<int>(std::count_if(i.live_nodes.begin(), i.live_nodes.end()
    │ │ │ │ -			, [](node_entry const& k) { return k.confirmed(); } ));
    │ │ │ │ -
    │ │ │ │ -		replacements += int(i.replacements.size());
    │ │ │ │ +		std::vector<sha1_hash> ids;
    │ │ │ │ +		for (auto& n : m_nodes)
    │ │ │ │ +			ids.push_back(n.second.dht.nid());
    │ │ │ │ +		m_storage.update_node_ids(ids);
    │ │ │ │  	}
    │ │ │ │ -	return std::make_tuple(nodes, replacements, confirmed);
    │ │ │ │ -}
    │ │ │ │  
    │ │ │ │ -
    relevance 0../src/kademlia/routing_table.cpp:518this need to take bucket "prefix" into account. It should be unified with add_node_impl()

    this need to take bucket "prefix" into account. It should be unified │ │ │ │ -with add_node_impl()

    ../src/kademlia/routing_table.cpp:518

    {
    │ │ │ │ -	for (auto i = m_buckets.begin() , end(m_buckets.end()); i != end; ++i)
    │ │ │ │ +	node* dht_tracker::get_node(node_id const& id, std::string const& family_name)
    │ │ │ │  	{
    │ │ │ │ -		for (auto j = i->replacements.begin(); j != i->replacements.end(); ++j)
    │ │ │ │ -		{
    │ │ │ │ -			if (j->addr() != ep.address()) continue;
    │ │ │ │ -			if (j->port() != ep.port()) continue;
    │ │ │ │ -			return std::make_tuple(&*j, i, &i->replacements);
    │ │ │ │ -		}
    │ │ │ │ -		for (auto j = i->live_nodes.begin(); j != i->live_nodes.end(); ++j)
    │ │ │ │ +		TORRENT_UNUSED(id);
    │ │ │ │ +		for (auto& n : m_nodes)
    │ │ │ │  		{
    │ │ │ │ -			if (j->addr() != ep.address()) continue;
    │ │ │ │ -			if (j->port() != ep.port()) continue;
    │ │ │ │ -			return std::make_tuple(&*j, i, &i->live_nodes);
    │ │ │ │ +
    if (n.second.dht.protocol_family_name() == family_name) │ │ │ │ +
    return &n.second.dht; │ │ │ │ } │ │ │ │ - } │ │ │ │ - return std::tuple<node_entry*, routing_table::table_t::iterator, bucket_t*> │ │ │ │ - {nullptr, m_buckets.end(), nullptr}; │ │ │ │ -} │ │ │ │ │ │ │ │ -
    void routing_table::fill_from_replacements(table_t::iterator bucket) │ │ │ │ -
    { │ │ │ │ - bucket_t& b = bucket->live_nodes; │ │ │ │ - bucket_t& rb = bucket->replacements; │ │ │ │ - int const bucket_size = bucket_limit(int(std::distance(m_buckets.begin(), bucket))); │ │ │ │ - │ │ │ │ - if (int(b.size()) >= bucket_size) return; │ │ │ │ - │ │ │ │ - // sort by RTT first, to find the node with the lowest │ │ │ │ - // RTT that is pinged │ │ │ │ - std::sort(rb.begin(), rb.end()); │ │ │ │ + return nullptr; │ │ │ │ + } │ │ │ │ │ │ │ │ - while (int(b.size()) < bucket_size && !rb.empty()) │ │ │ │ + void dht_tracker::get_peers(sha1_hash const& ih │ │ │ │ + , std::function<void(std::vector<tcp::endpoint> const&)> f) │ │ │ │ { │ │ │ │ - auto j = std::find_if(rb.begin(), rb.end(), std::bind(&node_entry::pinged, _1)); │ │ │ │ - if (j == rb.end()) break; │ │ │ │ - b.push_back(*j); │ │ │ │ - rb.erase(j); │ │ │ │ + for (auto& n : m_nodes) │ │ │ │ + n.second.dht.get_peers(ih, f, {}, {}); │ │ │ │ } │ │ │ │ -} │ │ │ │ │ │ │ │ -void routing_table::prune_empty_bucket() │ │ │ │ -{ │ │ │ │ - if (m_buckets.back().live_nodes.empty() │ │ │ │ - && m_buckets.back().replacements.empty()) │ │ │ │ + void dht_tracker::announce(sha1_hash const& ih, int listen_port │ │ │ │ + , announce_flags_t const flags │ │ │ │ + , std::function<void(std::vector<tcp::endpoint> const&)> f) │ │ │ │ { │ │ │ │ - m_buckets.erase(m_buckets.end() - 1); │ │ │ │ + for (auto& n : m_nodes) │ │ │ │ + n.second.dht.announce(ih, listen_port, flags, f); │ │ │ │ } │ │ │ │ -} │ │ │ │ │ │ │ │ -void routing_table::remove_node(node_entry* n, bucket_t* b) │ │ │ │ + void dht_tracker::sample_infohashes(udp::endpoint const& ep, sha1_hash const& target │ │ │ │ + , std::function<void(node_id │ │ │ │ + , time_duration │ │ │ │ + , int, std::vector<sha1_hash> │ │ │ │ + , std::vector<std::pair<sha1_hash, udp::endpoint>>)> f) │ │ │ │ + { │ │ │ │ + for (auto& n : m_nodes) │ │ │ │ + { │ │ │ │ + if (ep.protocol() != (n.first.get_external_address().is_v4() ? udp::v4() : udp::v6())) │ │ │ │
    relevance 0../include/libtorrent/torrent_info.hpp:729change the type to std::shared_ptr in C++17 it is used as if immutable, it cannot be const for technical reasons right now.

    change the type to std::shared_ptr in C++17 │ │ │ │ it is used as if immutable, it cannot be const for technical reasons │ │ │ │ right now.

    ../include/libtorrent/torrent_info.hpp:729

    │ │ │ │  		// these are the collections from outside of the info-dict. These are
    │ │ │ │  		// owning strings, since we only keep the info-section around, these
    │ │ │ │  		// cannot be pointers into that buffer.
    │ │ │ │  		std::vector<std::string> m_owned_collections;
    │ │ │ │ @@ -10393,144 +10393,116 @@
    │ │ │ │  		std::int32_t m_piece_hashes = 0;
    │ │ │ │  
    │ │ │ │  		// the number of bytes in m_info_section
    │ │ │ │  		std::int32_t m_info_section_size = 0;
    │ │ │ │  
    │ │ │ │  		// this is used when creating a torrent. If there's
    │ │ │ │  		// only one file there are cases where it's impossible
    │ │ │ │ -
    relevance 0../include/libtorrent/identify_client.hpp:48hide this declaration when deprecated functions are disabled, and remove its internal use

    hide this declaration when deprecated functions are disabled, and │ │ │ │ -remove its internal use

    ../include/libtorrent/identify_client.hpp:48

    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    │ │ │ │ -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    │ │ │ │ -POSSIBILITY OF SUCH DAMAGE.
    │ │ │ │ -
    │ │ │ │ -*/
    │ │ │ │ -
    │ │ │ │ -#ifndef TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
    │ │ │ │ -#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
    │ │ │ │ +
    relevance 0../include/libtorrent/piece_picker.hpp:823should this be allocated lazily?

    should this be allocated lazily?

    ../include/libtorrent/piece_picker.hpp:823

    		// download list it may live in now
    │ │ │ │ +		std::vector<downloading_piece>::iterator update_piece_state(
    │ │ │ │ +			std::vector<downloading_piece>::iterator dp);
    │ │ │ │  
    │ │ │ │ -#include "libtorrent/config.hpp"
    │ │ │ │ +	private:
    │ │ │ │  
    │ │ │ │ -#if TORRENT_ABI_VERSION == 1
    │ │ │ │ -#include "libtorrent/aux_/disable_warnings_push.hpp"
    │ │ │ │ -#include <boost/optional.hpp>
    │ │ │ │ -#include "libtorrent/aux_/disable_warnings_pop.hpp"
    │ │ │ │ +#if TORRENT_USE_ASSERTS || TORRENT_USE_INVARIANT_CHECKS
    │ │ │ │ +		index_range<download_queue_t> categories() const
    │ │ │ │ +		{ return {{}, piece_picker::piece_pos::num_download_categories}; }
    │ │ │ │  #endif
    │ │ │ │  
    │ │ │ │ -#include "libtorrent/peer_id.hpp"
    │ │ │ │ -#include "libtorrent/fingerprint.hpp"
    │ │ │ │ +		// the following vectors are mutable because they sometimes may
    │ │ │ │ +		// be updated lazily, triggered by const functions
    │ │ │ │  
    │ │ │ │ -
    namespace libtorrent { │ │ │ │ + // this maps indices to number of peers that has this piece and │ │ │ │ + // index into the m_piece_info vectors. │ │ │ │ + // piece_pos::we_have_index means that we have the piece, so it │ │ │ │ + // doesn't exist in the piece_info buckets │ │ │ │ + // pieces with the filtered flag set doesn't have entries in │ │ │ │ + // the m_piece_info buckets either │ │ │ │ +
    mutable aux::vector<piece_pos, piece_index_t> m_piece_map; │ │ │ │
    │ │ │ │ -namespace aux { │ │ │ │ - │ │ │ │ - TORRENT_EXTRA_EXPORT │ │ │ │ - std::string identify_client_impl(const peer_id& p); │ │ │ │ + // tracks the number of bytes in a specific piece that are part of a pad │ │ │ │ + // file. The padding is assumed to be at the end of the piece, and the │ │ │ │ + // blocks covered by the pad bytes are not picked by the piece picker │ │ │ │ + std::unordered_map<piece_index_t, int> m_pads_in_piece; │ │ │ │ │ │ │ │ -} │ │ │ │ + // when the adjacent_piece affinity is enabled, this contains the most │ │ │ │ + // recent "extents" of adjacent pieces that have been requested from │ │ │ │ + // this is mutable because it's updated by functions to pick pieces, which │ │ │ │ + // are const. That's an efficient place to update it, since it's being │ │ │ │ + // traversed already. │ │ │ │ + mutable std::vector<piece_extent_t> m_recent_extents; │ │ │ │ │ │ │ │ - // these functions don't really need to be public. This mechanism of │ │ │ │ - // advertising client software and version is also out-dated. │ │ │ │ + // the number of bytes of pad file set in this piece picker │ │ │ │ + std::int64_t m_num_pad_bytes = 0; │ │ │ │ │ │ │ │ - // This function can can be used to extract a string describing a client │ │ │ │ - // version from its peer-id. It will recognize most clients that have this │ │ │ │ - // kind of identification in the peer-id. │ │ │ │ - TORRENT_DEPRECATED_EXPORT │ │ │ │ - std::string identify_client(const peer_id& p); │ │ │ │ + // the number of pad blocks that we already have │ │ │ │ + std::int64_t m_have_pad_bytes = 0; │ │ │ │ │ │ │ │ -#if TORRENT_ABI_VERSION == 1 │ │ │ │ + // the number of pad blocks part of filtered pieces we don't have │ │ │ │ + std::int64_t m_filtered_pad_bytes = 0; │ │ │ │ │ │ │ │ -#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" │ │ │ │ + // the number of pad blocks we have that are also filtered │ │ │ │ + std::int64_t m_have_filtered_pad_bytes = 0; │ │ │ │ │ │ │ │ - // Returns an optional fingerprint if any can be identified from the peer │ │ │ │ - // id. This can be used to automate the identification of clients. It will │ │ │ │ - // not be able to identify peers with non- standard encodings. Only Azureus │ │ │ │ - // style, Shadow's style and Mainline style. │ │ │ │ - TORRENT_DEPRECATED_EXPORT │ │ │ │ - boost::optional<fingerprint> │ │ │ │ - client_fingerprint(peer_id const& p); │ │ │ │ + // the number of seeds. These are not added to │ │ │ │ + // the availability counters of the pieces │ │ │ │ + int m_seeds = 0; │ │ │ │ │ │ │ │ -#include "libtorrent/aux_/disable_warnings_pop.hpp" │ │ │ │ -
    relevance 0../include/libtorrent/socket_type.hpp:60move to aux

    move to aux

    ../include/libtorrent/socket_type.hpp:60

    namespace libtorrent {
    │ │ │ │ +		// this vector contains all piece indices that are pickable
    │ │ │ │ +
    relevance 0../include/libtorrent/piece_picker.hpp:895it would be more intuitive to account "wanted" pieces instead of filtered

    it would be more intuitive to account "wanted" pieces │ │ │ │ +instead of filtered

    ../include/libtorrent/piece_picker.hpp:895

    │ │ │ │ +		// this holds the information of the blocks in partially downloaded
    │ │ │ │ +		// pieces. the downloading_piece::info index point into this vector for
    │ │ │ │ +		// its storage
    │ │ │ │ +		aux::vector<block_info> m_block_info;
    │ │ │ │  
    │ │ │ │ -// A type describing kinds of sockets involved in various operations or events.
    │ │ │ │ -enum class socket_type_t : std::uint8_t {
    │ │ │ │ -	tcp,
    │ │ │ │ -	socks5,
    │ │ │ │ -	http,
    │ │ │ │ -	utp,
    │ │ │ │ -	i2p,
    │ │ │ │ -	tcp_ssl,
    │ │ │ │ -	socks5_ssl,
    │ │ │ │ -	http_ssl,
    │ │ │ │ -	utp_ssl,
    │ │ │ │ +		// these are block ranges in m_block_info that are free. The numbers
    │ │ │ │ +		// in here, when multiplied by blocks_per_piece is the index to the
    │ │ │ │ +		// first block in the range that's free to use by a new downloading_piece.
    │ │ │ │ +		// this is a free-list.
    │ │ │ │ +		std::vector<std::uint16_t> m_free_block_infos;
    │ │ │ │  
    │ │ │ │ -#if TORRENT_ABI_VERSION <= 2
    │ │ │ │ -	udp TORRENT_DEPRECATED_ENUM = utp,
    │ │ │ │ -#endif
    │ │ │ │ -};
    │ │ │ │ +		std::uint16_t m_blocks_in_last_piece = 0;
    │ │ │ │ +		int m_piece_size = 0;
    │ │ │ │ +		std::int64_t m_total_size = 0;
    │ │ │ │  
    │ │ │ │ -// return a short human readable name for types of socket
    │ │ │ │ -
    char const* socket_type_name(socket_type_t); │ │ │ │ + // the number of filtered pieces that we don't already │ │ │ │ + // have. total_number_of_pieces - number_of_pieces_we_have │ │ │ │ + // - num_filtered is supposed to the number of pieces │ │ │ │ + // we still want to download │ │ │ │ +
    int m_num_filtered = 0; │ │ │ │
    │ │ │ │ -} │ │ │ │ - │ │ │ │ -#endif │ │ │ │ -
    relevance 0../include/libtorrent/announce_entry.hpp:76include the number of peers received from this tracker, at last announce

    include the number of peers received from this tracker, at last │ │ │ │ -announce

    ../include/libtorrent/announce_entry.hpp:76

    │ │ │ │ -	struct TORRENT_EXPORT announce_infohash
    │ │ │ │ -	{
    │ │ │ │ -		// internal
    │ │ │ │ -		TORRENT_UNEXPORT announce_infohash();
    │ │ │ │ -
    │ │ │ │ -		// if this tracker has returned an error or warning message
    │ │ │ │ -		// that message is stored here
    │ │ │ │ -		std::string message;
    │ │ │ │ -
    │ │ │ │ -		// if this tracker failed the last time it was contacted
    │ │ │ │ -		// this error code specifies what error occurred
    │ │ │ │ -		error_code last_error;
    │ │ │ │ -
    │ │ │ │ -		// the time of next tracker announce
    │ │ │ │ -		time_point32 next_announce = (time_point32::min)();
    │ │ │ │ +		// the number of pieces we have that also are filtered
    │ │ │ │ +		int m_num_have_filtered = 0;
    │ │ │ │  
    │ │ │ │ -		// no announces before this time
    │ │ │ │ -		time_point32 min_announce = (time_point32::min)();
    │ │ │ │ +		// we have all pieces in the range [0, m_cursor)
    │ │ │ │ +		// m_cursor is the first piece we don't have
    │ │ │ │ +		piece_index_t m_cursor{0};
    │ │ │ │  
    │ │ │ │ -
    │ │ │ │ -
    // these are either -1 or the scrape information this tracker last │ │ │ │ - // responded with. *incomplete* is the current number of downloaders in │ │ │ │ - // the swarm, *complete* is the current number of seeds in the swarm and │ │ │ │ - // *downloaded* is the cumulative number of completed downloads of this │ │ │ │ - // torrent, since the beginning of time (from this tracker's point of │ │ │ │ - // view). │ │ │ │ + // we have all pieces in the range [m_reverse_cursor, end) │ │ │ │ + // m_reverse_cursor is the first piece where we also have │ │ │ │ + // all the subsequent pieces │ │ │ │ + piece_index_t m_reverse_cursor{0}; │ │ │ │ │ │ │ │ - // if this tracker has returned scrape data, these fields are filled in │ │ │ │ - // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts │ │ │ │ - // the number of current downloaders. ``complete`` counts the number of │ │ │ │ - // current peers completed the download, or "seeds". ``downloaded`` is the │ │ │ │ - // cumulative number of completed downloads. │ │ │ │ - int scrape_incomplete = -1; │ │ │ │ - int scrape_complete = -1; │ │ │ │ - int scrape_downloaded = -1; │ │ │ │ + // the number of pieces we have (i.e. passed hash check). │ │ │ │ + // This includes pieces that we have filtered but still have │ │ │ │ + int m_num_have = 0; │ │ │ │ │ │ │ │ - // the number of times in a row we have failed to announce to this │ │ │ │ - // tracker. │ │ │ │ - std::uint8_t fails : 7; │ │ │ │ + // if this is set to true, it means update_pieces() │ │ │ │ + // has to be called before accessing m_pieces. │ │ │ │ + mutable bool m_dirty = false; │ │ │ │ + public: │ │ │ │ │ │ │ │ - // true while we're waiting for a response from the tracker. │ │ │ │ - bool updating : 1; │ │ │ │ + enum { max_pieces = (std::numeric_limits<int>::max)() - 1 }; │ │ │ │ │ │ │ │ - // set to true when we get a valid response from an announce │ │ │ │ - // with event=started. If it is set, we won't send start in the subsequent │ │ │ │ - // announces. │ │ │ │ - bool start_sent : 1; │ │ │ │ + }; │ │ │ │ +} │ │ │ │ │ │ │ │ - // set to true when we send a event=completed. │ │ │ │ - bool complete_sent : 1; │ │ │ │ -
    relevance 0../include/libtorrent/torrent.hpp:280make this a raw pointer. perhaps keep the shared_ptr around further down the object to maintain an owner

    make this a raw pointer. perhaps keep the shared_ptr │ │ │ │ +#endif // TORRENT_PIECE_PICKER_HPP_INCLUDED │ │ │ │ +relevance 0../include/libtorrent/torrent.hpp:280make this a raw pointer. perhaps keep the shared_ptr around further down the object to maintain an owner

    make this a raw pointer. perhaps keep the shared_ptr │ │ │ │ around further down the object to maintain an owner

    ../include/libtorrent/torrent.hpp:280

    #endif
    │ │ │ │  	};
    │ │ │ │  
    │ │ │ │  	struct TORRENT_EXTRA_EXPORT torrent_hot_members
    │ │ │ │  	{
    │ │ │ │  		torrent_hot_members(aux::session_interface& ses
    │ │ │ │  			, add_torrent_params const& p, bool session_paused);
    │ │ │ │ @@ -10574,15 +10546,15 @@
    │ │ │ │  		// this is set to false as long as the connections
    │ │ │ │  		// of this torrent haven't been initialized. If we
    │ │ │ │  		// have metadata from the start, connections are
    │ │ │ │  		// initialized immediately, if we didn't have metadata,
    │ │ │ │  		// they are initialized right after files_checked().
    │ │ │ │  		// valid_resume_data() will return false as long as
    │ │ │ │  		// the connections aren't initialized, to avoid
    │ │ │ │ -
    relevance 0../include/libtorrent/torrent.hpp:463make graceful pause also finish all sending blocks before disconnecting

    make graceful pause also finish all sending blocks │ │ │ │ +relevance 0../include/libtorrent/torrent.hpp:463make graceful pause also finish all sending blocks before disconnecting

    make graceful pause also finish all sending blocks │ │ │ │ before disconnecting

    ../include/libtorrent/torrent.hpp:463

    │ │ │ │  		void on_resume_data_checked(status_t status, storage_error const& error);
    │ │ │ │  		void on_force_recheck(status_t status, storage_error const& error);
    │ │ │ │  		void on_piece_hashed(aux::vector<sha256_hash> block_hashes
    │ │ │ │  			, piece_index_t piece, sha1_hash const& piece_hash
    │ │ │ │  			, storage_error const& error);
    │ │ │ │  		void files_checked();
    │ │ │ │ @@ -10626,15 +10598,15 @@
    │ │ │ │  		void read_piece(piece_index_t);
    │ │ │ │  		void on_disk_read_complete(disk_buffer_holder, storage_error const&
    │ │ │ │  			, peer_request const&, std::shared_ptr<read_piece_struct>);
    │ │ │ │  
    │ │ │ │  		storage_mode_t storage_mode() const;
    │ │ │ │  
    │ │ │ │  		// this will flag the torrent as aborted. The main
    │ │ │ │ -
    relevance 0../include/libtorrent/torrent.hpp:600make this flag a combination of the other ones

    make this flag a combination │ │ │ │ +relevance 0../include/libtorrent/torrent.hpp:600make this flag a combination of the other ones

    make this flag a combination │ │ │ │ of the other ones

    ../include/libtorrent/torrent.hpp:600

    		void do_pause(bool was_paused = false);
    │ │ │ │  		void do_resume();
    │ │ │ │  
    │ │ │ │  		seconds32 finished_time() const;
    │ │ │ │  		seconds32 active_time() const;
    │ │ │ │  		seconds32 seeding_time() const;
    │ │ │ │  		seconds32 upload_mode_time() const;
    │ │ │ │ @@ -10678,15 +10650,15 @@
    │ │ │ │  		void set_piece_priority(piece_index_t index, download_priority_t priority);
    │ │ │ │  		download_priority_t piece_priority(piece_index_t index) const;
    │ │ │ │  
    │ │ │ │  		void prioritize_pieces(aux::vector<download_priority_t, piece_index_t> const& pieces);
    │ │ │ │  		void prioritize_piece_list(std::vector<std::pair<piece_index_t, download_priority_t>> const& pieces);
    │ │ │ │  		void piece_priorities(aux::vector<download_priority_t, piece_index_t>*) const;
    │ │ │ │  
    │ │ │ │ -
    relevance 0../include/libtorrent/torrent.hpp:1381this wastes 5 bits per file

    this wastes 5 bits per file

    ../include/libtorrent/torrent.hpp:1381

    #ifndef TORRENT_DISABLE_EXTENSIONS
    │ │ │ │ +
    relevance 0../include/libtorrent/torrent.hpp:1381this wastes 5 bits per file

    this wastes 5 bits per file

    ../include/libtorrent/torrent.hpp:1381

    #ifndef TORRENT_DISABLE_EXTENSIONS
    │ │ │ │  		std::list<std::shared_ptr<torrent_plugin>> m_extensions;
    │ │ │ │  #endif
    │ │ │ │  
    │ │ │ │  		// used for tracker announces
    │ │ │ │  		deadline_timer m_tracker_timer;
    │ │ │ │  
    │ │ │ │  		// used to detect when we are active or inactive for long enough
    │ │ │ │ @@ -10729,15 +10701,15 @@
    │ │ │ │  #if TORRENT_ABI_VERSION == 1
    │ │ │ │  		// deprecated in 1.1
    │ │ │ │  		std::string m_username;
    │ │ │ │  		std::string m_password;
    │ │ │ │  #endif
    │ │ │ │  
    │ │ │ │  		std::string m_save_path;
    │ │ │ │ -
    relevance 0../include/libtorrent/torrent.hpp:1696this member can probably be removed

    this member can probably be removed

    ../include/libtorrent/torrent.hpp:1696

    		unsigned int m_num_uploads:24;
    │ │ │ │ +
    relevance 0../include/libtorrent/torrent.hpp:1696this member can probably be removed

    this member can probably be removed

    ../include/libtorrent/torrent.hpp:1696

    		unsigned int m_num_uploads:24;
    │ │ │ │  
    │ │ │ │  		// 4 unused bits
    │ │ │ │  
    │ │ │ │  		// when this is true, this torrent supports peer exchange
    │ │ │ │  		bool m_enable_pex:1;
    │ │ │ │  
    │ │ │ │  		// set to true if the session IP filter applies to this
    │ │ │ │ @@ -10780,15 +10752,101 @@
    │ │ │ │  		// remember that this is an SSL torrent, so that we don't
    │ │ │ │  		// accidentally start seeding it without any authentication.
    │ │ │ │  		bool m_ssl_torrent:1;
    │ │ │ │  
    │ │ │ │  		// this is set to true if we're trying to delete the
    │ │ │ │  		// files belonging to it. When set, don't write any
    │ │ │ │  		// more blocks to disk!
    │ │ │ │ -
    relevance 0../include/libtorrent/peer_connection_interface.hpp:51make this interface smaller!

    make this interface smaller!

    ../include/libtorrent/peer_connection_interface.hpp:51

    │ │ │ │ +
    relevance 0../include/libtorrent/performance_counters.hpp:485some space could be saved here by making gauges 32 bits

    some space could be saved here by making gauges 32 bits

    ../include/libtorrent/performance_counters.hpp:485

    relevance 0../include/libtorrent/performance_counters.hpp:486restore these to regular integers. Instead have one copy of the counters per thread and collect them at convenient synchronization points

    restore these to regular integers. Instead have one copy │ │ │ │ +of the counters per thread and collect them at convenient │ │ │ │ +synchronization points

    ../include/libtorrent/performance_counters.hpp:486

    #ifdef ATOMIC_LLONG_LOCK_FREE
    │ │ │ │ +#define TORRENT_COUNTER_NOEXCEPT noexcept
    │ │ │ │ +#else
    │ │ │ │ +#define TORRENT_COUNTER_NOEXCEPT
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +		counters() TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +
    │ │ │ │ +		counters(counters const&) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +		counters& operator=(counters const&) & TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +
    │ │ │ │ +		// returns the new value
    │ │ │ │ +		std::int64_t inc_stats_counter(int c, std::int64_t value = 1) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +		std::int64_t operator[](int i) const TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +
    │ │ │ │ +		void set_value(int c, std::int64_t value) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +		void blend_stats_counter(int c, std::int64_t value, int ratio) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ +
    │ │ │ │ +	private:
    │ │ │ │ +
    │ │ │ │ +
    #ifdef ATOMIC_LLONG_LOCK_FREE │ │ │ │ +
    aux::array<std::atomic<std::int64_t>, num_counters> m_stats_counter; │ │ │ │ +#else │ │ │ │ + // if the atomic type isn't lock-free, use a single lock instead, for │ │ │ │ + // the whole array │ │ │ │ + mutable std::mutex m_mutex; │ │ │ │ + aux::array<std::int64_t, num_counters> m_stats_counter; │ │ │ │ +#endif │ │ │ │ + }; │ │ │ │ +} │ │ │ │ + │ │ │ │ +#endif │ │ │ │ +
    relevance 0../include/libtorrent/announce_entry.hpp:76include the number of peers received from this tracker, at last announce

    include the number of peers received from this tracker, at last │ │ │ │ +announce

    ../include/libtorrent/announce_entry.hpp:76

    │ │ │ │ +	struct TORRENT_EXPORT announce_infohash
    │ │ │ │ +	{
    │ │ │ │ +		// internal
    │ │ │ │ +		TORRENT_UNEXPORT announce_infohash();
    │ │ │ │ +
    │ │ │ │ +		// if this tracker has returned an error or warning message
    │ │ │ │ +		// that message is stored here
    │ │ │ │ +		std::string message;
    │ │ │ │ +
    │ │ │ │ +		// if this tracker failed the last time it was contacted
    │ │ │ │ +		// this error code specifies what error occurred
    │ │ │ │ +		error_code last_error;
    │ │ │ │ +
    │ │ │ │ +		// the time of next tracker announce
    │ │ │ │ +		time_point32 next_announce = (time_point32::min)();
    │ │ │ │ +
    │ │ │ │ +		// no announces before this time
    │ │ │ │ +		time_point32 min_announce = (time_point32::min)();
    │ │ │ │ +
    │ │ │ │ +
    │ │ │ │ +
    // these are either -1 or the scrape information this tracker last │ │ │ │ + // responded with. *incomplete* is the current number of downloaders in │ │ │ │ + // the swarm, *complete* is the current number of seeds in the swarm and │ │ │ │ + // *downloaded* is the cumulative number of completed downloads of this │ │ │ │ + // torrent, since the beginning of time (from this tracker's point of │ │ │ │ + // view). │ │ │ │ + │ │ │ │ + // if this tracker has returned scrape data, these fields are filled in │ │ │ │ + // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts │ │ │ │ + // the number of current downloaders. ``complete`` counts the number of │ │ │ │ + // current peers completed the download, or "seeds". ``downloaded`` is the │ │ │ │ + // cumulative number of completed downloads. │ │ │ │ + int scrape_incomplete = -1; │ │ │ │ + int scrape_complete = -1; │ │ │ │ + int scrape_downloaded = -1; │ │ │ │ + │ │ │ │ + // the number of times in a row we have failed to announce to this │ │ │ │ + // tracker. │ │ │ │ + std::uint8_t fails : 7; │ │ │ │ + │ │ │ │ + // true while we're waiting for a response from the tracker. │ │ │ │ + bool updating : 1; │ │ │ │ + │ │ │ │ + // set to true when we get a valid response from an announce │ │ │ │ + // with event=started. If it is set, we won't send start in the subsequent │ │ │ │ + // announces. │ │ │ │ + bool start_sent : 1; │ │ │ │ + │ │ │ │ + // set to true when we send a event=completed. │ │ │ │ + bool complete_sent : 1; │ │ │ │ +
    relevance 0../include/libtorrent/peer_connection_interface.hpp:51make this interface smaller!

    make this interface smaller!

    ../include/libtorrent/peer_connection_interface.hpp:51

    │ │ │ │  */
    │ │ │ │  
    │ │ │ │  #ifndef TORRENT_PEER_CONNECTION_INTERFACE_HPP
    │ │ │ │  #define TORRENT_PEER_CONNECTION_INTERFACE_HPP
    │ │ │ │  
    │ │ │ │  #include "libtorrent/fwd.hpp"
    │ │ │ │  #include "libtorrent/socket.hpp"
    │ │ │ │ @@ -10831,116 +10889,194 @@
    │ │ │ │  		virtual stat const& statistics() const = 0;
    │ │ │ │  		virtual void get_peer_info(peer_info& p) const = 0;
    │ │ │ │  #ifndef TORRENT_DISABLE_LOGGING
    │ │ │ │  		virtual bool should_log(peer_log_alert::direction_t direction) const = 0;
    │ │ │ │  		virtual void peer_log(peer_log_alert::direction_t direction
    │ │ │ │  			, char const* event, char const* fmt = "", ...) const noexcept TORRENT_FORMAT(4,5) = 0;
    │ │ │ │  #endif
    │ │ │ │ -
    relevance 0../include/libtorrent/piece_picker.hpp:823should this be allocated lazily?

    should this be allocated lazily?

    ../include/libtorrent/piece_picker.hpp:823

    		// download list it may live in now
    │ │ │ │ -		std::vector<downloading_piece>::iterator update_piece_state(
    │ │ │ │ -			std::vector<downloading_piece>::iterator dp);
    │ │ │ │ +
    relevance 0../include/libtorrent/hash_picker.hpp:155support batched adding of block hashes for reduced overhead?

    support batched adding of block hashes for reduced overhead?

    ../include/libtorrent/hash_picker.hpp:155

    		// the number of hashes in the range
    │ │ │ │ +		int count = 0;
    │ │ │ │ +		int proof_layers = 0;
    │ │ │ │ +	};
    │ │ │ │ +
    │ │ │ │ +	// validates the hash_request, to ensure its invariant as well as matching
    │ │ │ │ +	// the torrent's file_storage and the number of hashes accompanying the
    │ │ │ │ +	// request
    │ │ │ │ +	TORRENT_EXTRA_EXPORT
    │ │ │ │ +	bool validate_hash_request(hash_request const& hr, file_storage const& fs);
    │ │ │ │ +
    │ │ │ │ +	class TORRENT_EXTRA_EXPORT hash_picker
    │ │ │ │ +	{
    │ │ │ │ +	public:
    │ │ │ │ +		hash_picker(file_storage const& files
    │ │ │ │ +			, aux::vector<aux::merkle_tree, file_index_t>& trees);
    │ │ │ │ +
    │ │ │ │ +		hash_request pick_hashes(typed_bitfield<piece_index_t> const& pieces);
    │ │ │ │ +
    │ │ │ │ +		add_hashes_result add_hashes(hash_request const& req, span<sha256_hash const> hashes);
    │ │ │ │ +
    set_block_hash_result set_block_hash(piece_index_t piece, int offset, sha256_hash const& h); │ │ │ │ +
    void hashes_rejected(hash_request const& req); │ │ │ │ + void verify_block_hashes(piece_index_t index); │ │ │ │ + │ │ │ │ + // do we know the piece layer hash for a piece │ │ │ │ + bool have_hash(piece_index_t index) const; │ │ │ │ + // do we know all the block hashes for a file? │ │ │ │ + bool have_all(file_index_t file) const; │ │ │ │ + bool have_all() const; │ │ │ │ + bool piece_verified(piece_index_t piece) const; │ │ │ │ + │ │ │ │ + int piece_layer() const { return m_piece_layer; } │ │ │ │ │ │ │ │ private: │ │ │ │ + // returns the number of proof layers needed to verify the node's hash │ │ │ │ + int layers_to_verify(node_index idx) const; │ │ │ │ + int file_num_layers(file_index_t idx) const; │ │ │ │ │ │ │ │ -#if TORRENT_USE_ASSERTS || TORRENT_USE_INVARIANT_CHECKS │ │ │ │ - index_range<download_queue_t> categories() const │ │ │ │ - { return {{}, piece_picker::piece_pos::num_download_categories}; } │ │ │ │ + struct piece_hash_request │ │ │ │ + { │ │ │ │ + time_point last_request = min_time(); │ │ │ │ + int num_requests = 0; │ │ │ │ + bool have = false; │ │ │ │ + }; │ │ │ │ + │ │ │ │ + struct priority_block_request │ │ │ │ + { │ │ │ │ + priority_block_request(file_index_t const f, int const b) │ │ │ │ + : file(f), block(b) {} │ │ │ │ + file_index_t file; │ │ │ │ + int block; │ │ │ │ +
    relevance 0../include/libtorrent/identify_client.hpp:48hide this declaration when deprecated functions are disabled, and remove its internal use

    hide this declaration when deprecated functions are disabled, and │ │ │ │ +remove its internal use

    ../include/libtorrent/identify_client.hpp:48

    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    │ │ │ │ +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    │ │ │ │ +POSSIBILITY OF SUCH DAMAGE.
    │ │ │ │ +
    │ │ │ │ +*/
    │ │ │ │ +
    │ │ │ │ +#ifndef TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
    │ │ │ │ +#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED
    │ │ │ │ +
    │ │ │ │ +#include "libtorrent/config.hpp"
    │ │ │ │ +
    │ │ │ │ +#if TORRENT_ABI_VERSION == 1
    │ │ │ │ +#include "libtorrent/aux_/disable_warnings_push.hpp"
    │ │ │ │ +#include <boost/optional.hpp>
    │ │ │ │ +#include "libtorrent/aux_/disable_warnings_pop.hpp"
    │ │ │ │  #endif
    │ │ │ │  
    │ │ │ │ -		// the following vectors are mutable because they sometimes may
    │ │ │ │ -		// be updated lazily, triggered by const functions
    │ │ │ │ +#include "libtorrent/peer_id.hpp"
    │ │ │ │ +#include "libtorrent/fingerprint.hpp"
    │ │ │ │  
    │ │ │ │ -		// this maps indices to number of peers that has this piece and
    │ │ │ │ -		// index into the m_piece_info vectors.
    │ │ │ │ -		// piece_pos::we_have_index means that we have the piece, so it
    │ │ │ │ -		// doesn't exist in the piece_info buckets
    │ │ │ │ -		// pieces with the filtered flag set doesn't have entries in
    │ │ │ │ -		// the m_piece_info buckets either
    │ │ │ │ -
    mutable aux::vector<piece_pos, piece_index_t> m_piece_map; │ │ │ │ +
    namespace libtorrent { │ │ │ │
    │ │ │ │ - // tracks the number of bytes in a specific piece that are part of a pad │ │ │ │ - // file. The padding is assumed to be at the end of the piece, and the │ │ │ │ - // blocks covered by the pad bytes are not picked by the piece picker │ │ │ │ - std::unordered_map<piece_index_t, int> m_pads_in_piece; │ │ │ │ +namespace aux { │ │ │ │ │ │ │ │ - // when the adjacent_piece affinity is enabled, this contains the most │ │ │ │ - // recent "extents" of adjacent pieces that have been requested from │ │ │ │ - // this is mutable because it's updated by functions to pick pieces, which │ │ │ │ - // are const. That's an efficient place to update it, since it's being │ │ │ │ - // traversed already. │ │ │ │ - mutable std::vector<piece_extent_t> m_recent_extents; │ │ │ │ + TORRENT_EXTRA_EXPORT │ │ │ │ + std::string identify_client_impl(const peer_id& p); │ │ │ │ │ │ │ │ - // the number of bytes of pad file set in this piece picker │ │ │ │ - std::int64_t m_num_pad_bytes = 0; │ │ │ │ +} │ │ │ │ │ │ │ │ - // the number of pad blocks that we already have │ │ │ │ - std::int64_t m_have_pad_bytes = 0; │ │ │ │ + // these functions don't really need to be public. This mechanism of │ │ │ │ + // advertising client software and version is also out-dated. │ │ │ │ │ │ │ │ - // the number of pad blocks part of filtered pieces we don't have │ │ │ │ - std::int64_t m_filtered_pad_bytes = 0; │ │ │ │ + // This function can can be used to extract a string describing a client │ │ │ │ + // version from its peer-id. It will recognize most clients that have this │ │ │ │ + // kind of identification in the peer-id. │ │ │ │ + TORRENT_DEPRECATED_EXPORT │ │ │ │ + std::string identify_client(const peer_id& p); │ │ │ │ │ │ │ │ - // the number of pad blocks we have that are also filtered │ │ │ │ - std::int64_t m_have_filtered_pad_bytes = 0; │ │ │ │ +#if TORRENT_ABI_VERSION == 1 │ │ │ │ │ │ │ │ - // the number of seeds. These are not added to │ │ │ │ - // the availability counters of the pieces │ │ │ │ - int m_seeds = 0; │ │ │ │ +#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" │ │ │ │ │ │ │ │ - // this vector contains all piece indices that are pickable │ │ │ │ -
    relevance 0../include/libtorrent/piece_picker.hpp:895it would be more intuitive to account "wanted" pieces instead of filtered

    it would be more intuitive to account "wanted" pieces │ │ │ │ -instead of filtered

    ../include/libtorrent/piece_picker.hpp:895

    │ │ │ │ -		// this holds the information of the blocks in partially downloaded
    │ │ │ │ -		// pieces. the downloading_piece::info index point into this vector for
    │ │ │ │ -		// its storage
    │ │ │ │ -		aux::vector<block_info> m_block_info;
    │ │ │ │ +	// Returns an optional fingerprint if any can be identified from the peer
    │ │ │ │ +	// id. This can be used to automate the identification of clients. It will
    │ │ │ │ +	// not be able to identify peers with non- standard encodings. Only Azureus
    │ │ │ │ +	// style, Shadow's style and Mainline style.
    │ │ │ │ +	TORRENT_DEPRECATED_EXPORT
    │ │ │ │ +	boost::optional<fingerprint>
    │ │ │ │ +		client_fingerprint(peer_id const& p);
    │ │ │ │  
    │ │ │ │ -		// these are block ranges in m_block_info that are free. The numbers
    │ │ │ │ -		// in here, when multiplied by blocks_per_piece is the index to the
    │ │ │ │ -		// first block in the range that's free to use by a new downloading_piece.
    │ │ │ │ -		// this is a free-list.
    │ │ │ │ -		std::vector<std::uint16_t> m_free_block_infos;
    │ │ │ │ +#include "libtorrent/aux_/disable_warnings_pop.hpp"
    │ │ │ │ +
    relevance 0../include/libtorrent/upnp.hpp:162support using the windows API for UPnP operations as well

    support using the windows API for UPnP operations as well

    ../include/libtorrent/upnp.hpp:162

    {
    │ │ │ │ +	bool in_error_code = false;
    │ │ │ │ +	bool exit = false;
    │ │ │ │ +	int error_code = -1;
    │ │ │ │ +};
    │ │ │ │  
    │ │ │ │ -		std::uint16_t m_blocks_in_last_piece = 0;
    │ │ │ │ -		int m_piece_size = 0;
    │ │ │ │ -		std::int64_t m_total_size = 0;
    │ │ │ │ +struct ip_address_parse_state: error_code_parse_state
    │ │ │ │ +{
    │ │ │ │ +	bool in_ip_address = false;
    │ │ │ │ +	std::string ip_address;
    │ │ │ │ +};
    │ │ │ │  
    │ │ │ │ -		// the number of filtered pieces that we don't already
    │ │ │ │ -		// have. total_number_of_pieces - number_of_pieces_we_have
    │ │ │ │ -		// - num_filtered is supposed to the number of pieces
    │ │ │ │ -		// we still want to download
    │ │ │ │ -
    int m_num_filtered = 0; │ │ │ │ -
    │ │ │ │ - // the number of pieces we have that also are filtered │ │ │ │ - int m_num_have_filtered = 0; │ │ │ │ +TORRENT_EXTRA_EXPORT void find_control_url(int type, string_view, parse_state& state); │ │ │ │ │ │ │ │ - // we have all pieces in the range [0, m_cursor) │ │ │ │ - // m_cursor is the first piece we don't have │ │ │ │ - piece_index_t m_cursor{0}; │ │ │ │ +TORRENT_EXTRA_EXPORT void find_error_code(int type, string_view string │ │ │ │ + , error_code_parse_state& state); │ │ │ │ │ │ │ │ - // we have all pieces in the range [m_reverse_cursor, end) │ │ │ │ - // m_reverse_cursor is the first piece where we also have │ │ │ │ - // all the subsequent pieces │ │ │ │ - piece_index_t m_reverse_cursor{0}; │ │ │ │ +TORRENT_EXTRA_EXPORT void find_ip_address(int type, string_view string │ │ │ │ + , ip_address_parse_state& state); │ │ │ │ │ │ │ │ - // the number of pieces we have (i.e. passed hash check). │ │ │ │ - // This includes pieces that we have filtered but still have │ │ │ │ - int m_num_have = 0; │ │ │ │ +
    struct TORRENT_EXTRA_EXPORT upnp final │ │ │ │ +
    : std::enable_shared_from_this<upnp> │ │ │ │ + , single_threaded │ │ │ │ +{ │ │ │ │ + upnp(io_context& ios │ │ │ │ + , aux::session_settings const& settings │ │ │ │ + , aux::portmap_callback& cb │ │ │ │ + , address_v4 listen_address │ │ │ │ + , address_v4 netmask │ │ │ │ + , std::string listen_device │ │ │ │ + , aux::listen_socket_handle ls); │ │ │ │ + ~upnp(); │ │ │ │ │ │ │ │ - // if this is set to true, it means update_pieces() │ │ │ │ - // has to be called before accessing m_pieces. │ │ │ │ - mutable bool m_dirty = false; │ │ │ │ - public: │ │ │ │ + void start(); │ │ │ │ │ │ │ │ - enum { max_pieces = (std::numeric_limits<int>::max)() - 1 }; │ │ │ │ + // Attempts to add a port mapping for the specified protocol. Valid protocols are │ │ │ │ + // ``upnp::tcp`` and ``upnp::udp`` for the UPnP class and ``natpmp::tcp`` and │ │ │ │ + // ``natpmp::udp`` for the NAT-PMP class. │ │ │ │ + // │ │ │ │ + // ``external_port`` is the port on the external address that will be mapped. This │ │ │ │ + // is a hint, you are not guaranteed that this port will be available, and it may │ │ │ │ + // end up being something else. In the portmap_alert_ notification, the actual │ │ │ │ + // external port is reported. │ │ │ │ + // │ │ │ │ + // ``local_port`` is the port in the local machine that the mapping should forward │ │ │ │ + // to. │ │ │ │ + // │ │ │ │ + // The return value is an index that identifies this port mapping. This is used │ │ │ │ + // to refer to mappings that fails or succeeds in the portmap_error_alert_ and │ │ │ │ + // portmap_alert_ respectively. If The mapping fails immediately, the return value │ │ │ │ + // is -1, which means failure. There will not be any error alert notification for │ │ │ │ +
    relevance 0../include/libtorrent/socket_type.hpp:60move to aux

    move to aux

    ../include/libtorrent/socket_type.hpp:60

    namespace libtorrent {
    │ │ │ │  
    │ │ │ │ -	};
    │ │ │ │ +// A type describing kinds of sockets involved in various operations or events.
    │ │ │ │ +enum class socket_type_t : std::uint8_t {
    │ │ │ │ +	tcp,
    │ │ │ │ +	socks5,
    │ │ │ │ +	http,
    │ │ │ │ +	utp,
    │ │ │ │ +	i2p,
    │ │ │ │ +	tcp_ssl,
    │ │ │ │ +	socks5_ssl,
    │ │ │ │ +	http_ssl,
    │ │ │ │ +	utp_ssl,
    │ │ │ │ +
    │ │ │ │ +#if TORRENT_ABI_VERSION <= 2
    │ │ │ │ +	udp TORRENT_DEPRECATED_ENUM = utp,
    │ │ │ │ +#endif
    │ │ │ │ +};
    │ │ │ │ +
    │ │ │ │ +// return a short human readable name for types of socket
    │ │ │ │ +
    char const* socket_type_name(socket_type_t); │ │ │ │ +
    │ │ │ │ } │ │ │ │ │ │ │ │ -#endif // TORRENT_PIECE_PICKER_HPP_INCLUDED │ │ │ │ -
    relevance 0../include/libtorrent/i2p_stream.hpp:533make this a string_view

    make this a string_view

    ../include/libtorrent/i2p_stream.hpp:533

    │ │ │ │ +#endif
    │ │ │ │ +
    relevance 0../include/libtorrent/i2p_stream.hpp:533make this a string_view

    make this a string_view

    ../include/libtorrent/i2p_stream.hpp:533

    │ │ │ │  		char tmp[20];
    │ │ │ │  		aux::random_bytes(tmp);
    │ │ │ │  		m_session_id.resize(sizeof(tmp)*2);
    │ │ │ │  		aux::to_hex(tmp, &m_session_id[0]);
    │ │ │ │  
    │ │ │ │  		m_sam_socket = std::make_shared<i2p_stream>(m_io_service);
    │ │ │ │  		m_sam_socket->set_proxy(m_hostname, m_port);
    │ │ │ │ @@ -10983,15 +11119,67 @@
    │ │ │ │  			return;
    │ │ │ │  		}
    │ │ │ │  
    │ │ │ │  		do_name_lookup("ME", wrap_allocator(
    │ │ │ │  			[this](error_code const& e, char const* dst, Handler hn) {
    │ │ │ │  				set_local_endpoint(e, dst, std::move(hn));
    │ │ │ │  			}, std::move(h)));
    │ │ │ │ -
    relevance 0../include/libtorrent/string_view.hpp:40replace this by the standard string_view in C++17

    replace this by the standard string_view in C++17

    ../include/libtorrent/string_view.hpp:40

    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    │ │ │ │ +
    relevance 0../include/libtorrent/proxy_base.hpp:227it would be nice to remember the bind port and bind once we know where the proxy is m_sock.bind(endpoint, ec);

    it would be nice to remember the bind port and bind once we know where the proxy is │ │ │ │ +m_sock.bind(endpoint, ec);

    ../include/libtorrent/proxy_base.hpp:227

    		TORRENT_ASSERT(m_magic == 0x1337);
    │ │ │ │ +		m_sock.cancel();
    │ │ │ │ +	}
    │ │ │ │ +
    │ │ │ │ +	void cancel(error_code& ec)
    │ │ │ │ +	{
    │ │ │ │ +		TORRENT_ASSERT(m_magic == 0x1337);
    │ │ │ │ +		m_sock.cancel(ec);
    │ │ │ │ +	}
    │ │ │ │ +
    │ │ │ │ +	void bind(endpoint_type const& /* endpoint */, error_code& /* ec */)
    │ │ │ │ +	{
    │ │ │ │ +		TORRENT_ASSERT(m_magic == 0x1337);
    │ │ │ │ +		// the reason why we ignore binds here is because we don't
    │ │ │ │ +		// (necessarily) yet know what address family the proxy
    │ │ │ │ +		// will resolve to, and binding to the wrong one would
    │ │ │ │ +		// break our connection attempt later. The caller here
    │ │ │ │ +		// doesn't necessarily know that we're proxying, so this
    │ │ │ │ +		// bind address is based on the final endpoint, not the
    │ │ │ │ +		// proxy.
    │ │ │ │ +
    } │ │ │ │ +
    │ │ │ │ +#ifndef BOOST_NO_EXCEPTIONS │ │ │ │ + void open(protocol_type const&) │ │ │ │ + { │ │ │ │ + TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ +// m_sock.open(p); │ │ │ │ + } │ │ │ │ +#endif │ │ │ │ + │ │ │ │ + void open(protocol_type const&, error_code&) │ │ │ │ + { │ │ │ │ + TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ + // we need to ignore this for the same reason as stated │ │ │ │ + // for ignoring bind() │ │ │ │ +// m_sock.open(p, ec); │ │ │ │ + } │ │ │ │ + │ │ │ │ +#ifndef BOOST_NO_EXCEPTIONS │ │ │ │ + void close() │ │ │ │ + { │ │ │ │ + TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ + m_remote_endpoint = endpoint_type(); │ │ │ │ + m_sock.close(); │ │ │ │ + m_resolver.cancel(); │ │ │ │ + } │ │ │ │ +#endif │ │ │ │ + │ │ │ │ + void close(error_code& ec) │ │ │ │ + { │ │ │ │ + TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ +
    relevance 0../include/libtorrent/string_view.hpp:40replace this by the standard string_view in C++17

    replace this by the standard string_view in C++17

    ../include/libtorrent/string_view.hpp:40

    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    │ │ │ │  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    │ │ │ │  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    │ │ │ │  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    │ │ │ │  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    │ │ │ │  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    │ │ │ │  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    │ │ │ │  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    │ │ │ │ @@ -11034,118 +11222,67 @@
    │ │ │ │  {
    │ │ │ │  	while (pos < v.size())
    │ │ │ │  	{
    │ │ │ │  		if (std::strchr(c, v[pos]) != nullptr) return pos;
    │ │ │ │  		++pos;
    │ │ │ │  	}
    │ │ │ │  	return string_view::npos;
    │ │ │ │ -
    relevance 0../include/libtorrent/hash_picker.hpp:155support batched adding of block hashes for reduced overhead?

    support batched adding of block hashes for reduced overhead?

    ../include/libtorrent/hash_picker.hpp:155

    		// the number of hashes in the range
    │ │ │ │ -		int count = 0;
    │ │ │ │ -		int proof_layers = 0;
    │ │ │ │ -	};
    │ │ │ │ +
    relevance 0../include/libtorrent/socks5_stream.hpp:197we could bind the socket here, since we know what the target endpoint is of the proxy

    we could bind the socket here, since we know what the │ │ │ │ +target endpoint is of the proxy

    ../include/libtorrent/socks5_stream.hpp:197

    			}, std::move(handler)));
    │ │ │ │ +	}
    │ │ │ │  
    │ │ │ │ -	// validates the hash_request, to ensure its invariant as well as matching
    │ │ │ │ -	// the torrent's file_storage and the number of hashes accompanying the
    │ │ │ │ -	// request
    │ │ │ │ -	TORRENT_EXTRA_EXPORT
    │ │ │ │ -	bool validate_hash_request(hash_request const& hr, file_storage const& fs);
    │ │ │ │ +private:
    │ │ │ │  
    │ │ │ │ -	class TORRENT_EXTRA_EXPORT hash_picker
    │ │ │ │ +	template <typename Handler>
    │ │ │ │ +	void name_lookup(error_code const& e, tcp::resolver::results_type ips
    │ │ │ │ +		, Handler h)
    │ │ │ │  	{
    │ │ │ │ -	public:
    │ │ │ │ -		hash_picker(file_storage const& files
    │ │ │ │ -			, aux::vector<aux::merkle_tree, file_index_t>& trees);
    │ │ │ │ -
    │ │ │ │ -		hash_request pick_hashes(typed_bitfield<piece_index_t> const& pieces);
    │ │ │ │ -
    │ │ │ │ -		add_hashes_result add_hashes(hash_request const& req, span<sha256_hash const> hashes);
    │ │ │ │ -
    set_block_hash_result set_block_hash(piece_index_t piece, int offset, sha256_hash const& h); │ │ │ │ -
    void hashes_rejected(hash_request const& req); │ │ │ │ - void verify_block_hashes(piece_index_t index); │ │ │ │ - │ │ │ │ - // do we know the piece layer hash for a piece │ │ │ │ - bool have_hash(piece_index_t index) const; │ │ │ │ - // do we know all the block hashes for a file? │ │ │ │ - bool have_all(file_index_t file) const; │ │ │ │ - bool have_all() const; │ │ │ │ - bool piece_verified(piece_index_t piece) const; │ │ │ │ - │ │ │ │ - int piece_layer() const { return m_piece_layer; } │ │ │ │ - │ │ │ │ - private: │ │ │ │ - // returns the number of proof layers needed to verify the node's hash │ │ │ │ - int layers_to_verify(node_index idx) const; │ │ │ │ - int file_num_layers(file_index_t idx) const; │ │ │ │ - │ │ │ │ - struct piece_hash_request │ │ │ │ - { │ │ │ │ - time_point last_request = min_time(); │ │ │ │ - int num_requests = 0; │ │ │ │ - bool have = false; │ │ │ │ - }; │ │ │ │ + COMPLETE_ASYNC("socks5_stream::name_lookup"); │ │ │ │ + if (handle_error(e, std::move(h))) return; │ │ │ │ │ │ │ │ - struct priority_block_request │ │ │ │ + auto i = ips.begin(); │ │ │ │ + if (!m_sock.is_open()) │ │ │ │ { │ │ │ │ - priority_block_request(file_index_t const f, int const b) │ │ │ │ - : file(f), block(b) {} │ │ │ │ - file_index_t file; │ │ │ │ - int block; │ │ │ │ -
    relevance 0../include/libtorrent/proxy_base.hpp:227it would be nice to remember the bind port and bind once we know where the proxy is m_sock.bind(endpoint, ec);

    it would be nice to remember the bind port and bind once we know where the proxy is │ │ │ │ -m_sock.bind(endpoint, ec);

    ../include/libtorrent/proxy_base.hpp:227

    		TORRENT_ASSERT(m_magic == 0x1337);
    │ │ │ │ -		m_sock.cancel();
    │ │ │ │ -	}
    │ │ │ │ -
    │ │ │ │ -	void cancel(error_code& ec)
    │ │ │ │ -	{
    │ │ │ │ -		TORRENT_ASSERT(m_magic == 0x1337);
    │ │ │ │ -		m_sock.cancel(ec);
    │ │ │ │ -	}
    │ │ │ │ -
    │ │ │ │ -	void bind(endpoint_type const& /* endpoint */, error_code& /* ec */)
    │ │ │ │ -	{
    │ │ │ │ -		TORRENT_ASSERT(m_magic == 0x1337);
    │ │ │ │ -		// the reason why we ignore binds here is because we don't
    │ │ │ │ -		// (necessarily) yet know what address family the proxy
    │ │ │ │ -		// will resolve to, and binding to the wrong one would
    │ │ │ │ -		// break our connection attempt later. The caller here
    │ │ │ │ -		// doesn't necessarily know that we're proxying, so this
    │ │ │ │ -		// bind address is based on the final endpoint, not the
    │ │ │ │ -		// proxy.
    │ │ │ │ -
    } │ │ │ │ -
    │ │ │ │ -#ifndef BOOST_NO_EXCEPTIONS │ │ │ │ - void open(protocol_type const&) │ │ │ │ - { │ │ │ │ - TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ -// m_sock.open(p); │ │ │ │ - } │ │ │ │ -#endif │ │ │ │ + error_code ec; │ │ │ │ + m_sock.open(i->endpoint().protocol(), ec); │ │ │ │ + if (handle_error(ec, std::move(h))) return; │ │ │ │ + } │ │ │ │ │ │ │ │ - void open(protocol_type const&, error_code&) │ │ │ │ - { │ │ │ │ - TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ - // we need to ignore this for the same reason as stated │ │ │ │ - // for ignoring bind() │ │ │ │ -// m_sock.open(p, ec); │ │ │ │ +
    ADD_OUTSTANDING_ASYNC("socks5_stream::connected"); │ │ │ │ +
    m_sock.async_connect(i->endpoint(), wrap_allocator( │ │ │ │ + [this](error_code const& ec, Handler hn) │ │ │ │ + { connected(ec, std::move(hn)); }, std::move(h))); │ │ │ │ } │ │ │ │ │ │ │ │ -#ifndef BOOST_NO_EXCEPTIONS │ │ │ │ - void close() │ │ │ │ + template <typename Handler> │ │ │ │ + void connected(error_code const& e, Handler h) │ │ │ │ { │ │ │ │ - TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ - m_remote_endpoint = endpoint_type(); │ │ │ │ - m_sock.close(); │ │ │ │ - m_resolver.cancel(); │ │ │ │ - } │ │ │ │ -#endif │ │ │ │ + COMPLETE_ASYNC("socks5_stream::connected"); │ │ │ │ + if (handle_error(e, std::move(h))) return; │ │ │ │ │ │ │ │ - void close(error_code& ec) │ │ │ │ - { │ │ │ │ - TORRENT_ASSERT(m_magic == 0x1337); │ │ │ │ -
    relevance 0../include/libtorrent/peer_connection.hpp:218make this a raw pointer (to save size in the first cache line) and make the constructor take a raw pointer. torrent objects should always outlive their peers

    make this a raw pointer (to save size in │ │ │ │ + using namespace libtorrent::aux; │ │ │ │ + if (m_version == 5) │ │ │ │ + { │ │ │ │ + // send SOCKS5 authentication methods │ │ │ │ + m_buffer.resize(m_user.empty()?3:4); │ │ │ │ + char* p = &m_buffer[0]; │ │ │ │ + write_uint8(5, p); // SOCKS VERSION 5 │ │ │ │ + if (m_user.empty()) │ │ │ │ + { │ │ │ │ + write_uint8(1, p); // 1 authentication method (no auth) │ │ │ │ + write_uint8(0, p); // no authentication │ │ │ │ + } │ │ │ │ + else │ │ │ │ + { │ │ │ │ + write_uint8(2, p); // 2 authentication methods │ │ │ │ + write_uint8(0, p); // no authentication │ │ │ │ + write_uint8(2, p); // username/password │ │ │ │ + } │ │ │ │ + ADD_OUTSTANDING_ASYNC("socks5_stream::handshake1"); │ │ │ │ +relevance 0../include/libtorrent/peer_connection.hpp:218make this a raw pointer (to save size in the first cache line) and make the constructor take a raw pointer. torrent objects should always outlive their peers

    make this a raw pointer (to save size in │ │ │ │ the first cache line) and make the constructor │ │ │ │ take a raw pointer. torrent objects should always │ │ │ │ outlive their peers

    ../include/libtorrent/peer_connection.hpp:218

    			, m_snubbed(false)
    │ │ │ │  			, m_interesting(false)
    │ │ │ │  			, m_choked(true)
    │ │ │ │  			, m_ignore_stats(false)
    │ │ │ │  		{}
    │ │ │ │ @@ -11191,15 +11328,15 @@
    │ │ │ │  		// time out is reached.
    │ │ │ │  		bool m_connecting:1;
    │ │ │ │  
    │ │ │ │  		// this is set to true if the last time we tried to
    │ │ │ │  		// pick a piece to download, we could only find
    │ │ │ │  		// blocks that were already requested from other
    │ │ │ │  		// peers. In this case, we should not try to pick
    │ │ │ │ -
    relevance 0../include/libtorrent/peer_connection.hpp:1026factor this out into its own class with a virtual interface torrent and session should implement this interface

    factor this out into its own class with a virtual interface │ │ │ │ +relevance 0../include/libtorrent/peer_connection.hpp:1026factor this out into its own class with a virtual interface torrent and session should implement this interface

    factor this out into its own class with a virtual interface │ │ │ │ torrent and session should implement this interface

    ../include/libtorrent/peer_connection.hpp:1026

    │ │ │ │  		// the local endpoint for this peer, i.e. our address
    │ │ │ │  		// and our port. If this is set for outgoing connections
    │ │ │ │  		// before the connection completes, it means we want to
    │ │ │ │  		// force the connection to be bound to the specified interface.
    │ │ │ │  		// if it ends up being bound to a different local IP, the connection
    │ │ │ │  		// is closed.
    │ │ │ │ @@ -11243,151 +11380,14 @@
    │ │ │ │  		// let plugins control flags that should always be set
    │ │ │ │  		picker_options_t m_picker_options{};
    │ │ │ │  
    │ │ │ │  		// the number of invalid piece-requests
    │ │ │ │  		// we have got from this peer. If the request
    │ │ │ │  		// queue gets empty, and there have been
    │ │ │ │  		// invalid requests, we can assume the
    │ │ │ │ -
    relevance 0../include/libtorrent/socks5_stream.hpp:197we could bind the socket here, since we know what the target endpoint is of the proxy

    we could bind the socket here, since we know what the │ │ │ │ -target endpoint is of the proxy

    ../include/libtorrent/socks5_stream.hpp:197

    			}, std::move(handler)));
    │ │ │ │ -	}
    │ │ │ │ -
    │ │ │ │ -private:
    │ │ │ │ -
    │ │ │ │ -	template <typename Handler>
    │ │ │ │ -	void name_lookup(error_code const& e, tcp::resolver::results_type ips
    │ │ │ │ -		, Handler h)
    │ │ │ │ -	{
    │ │ │ │ -		COMPLETE_ASYNC("socks5_stream::name_lookup");
    │ │ │ │ -		if (handle_error(e, std::move(h))) return;
    │ │ │ │ -
    │ │ │ │ -		auto i = ips.begin();
    │ │ │ │ -		if (!m_sock.is_open())
    │ │ │ │ -		{
    │ │ │ │ -			error_code ec;
    │ │ │ │ -			m_sock.open(i->endpoint().protocol(), ec);
    │ │ │ │ -			if (handle_error(ec, std::move(h))) return;
    │ │ │ │ -		}
    │ │ │ │ -
    │ │ │ │ -
    ADD_OUTSTANDING_ASYNC("socks5_stream::connected"); │ │ │ │ -
    m_sock.async_connect(i->endpoint(), wrap_allocator( │ │ │ │ - [this](error_code const& ec, Handler hn) │ │ │ │ - { connected(ec, std::move(hn)); }, std::move(h))); │ │ │ │ - } │ │ │ │ - │ │ │ │ - template <typename Handler> │ │ │ │ - void connected(error_code const& e, Handler h) │ │ │ │ - { │ │ │ │ - COMPLETE_ASYNC("socks5_stream::connected"); │ │ │ │ - if (handle_error(e, std::move(h))) return; │ │ │ │ - │ │ │ │ - using namespace libtorrent::aux; │ │ │ │ - if (m_version == 5) │ │ │ │ - { │ │ │ │ - // send SOCKS5 authentication methods │ │ │ │ - m_buffer.resize(m_user.empty()?3:4); │ │ │ │ - char* p = &m_buffer[0]; │ │ │ │ - write_uint8(5, p); // SOCKS VERSION 5 │ │ │ │ - if (m_user.empty()) │ │ │ │ - { │ │ │ │ - write_uint8(1, p); // 1 authentication method (no auth) │ │ │ │ - write_uint8(0, p); // no authentication │ │ │ │ - } │ │ │ │ - else │ │ │ │ - { │ │ │ │ - write_uint8(2, p); // 2 authentication methods │ │ │ │ - write_uint8(0, p); // no authentication │ │ │ │ - write_uint8(2, p); // username/password │ │ │ │ - } │ │ │ │ - ADD_OUTSTANDING_ASYNC("socks5_stream::handshake1"); │ │ │ │ -
    relevance 0../include/libtorrent/upnp.hpp:162support using the windows API for UPnP operations as well

    support using the windows API for UPnP operations as well

    ../include/libtorrent/upnp.hpp:162

    {
    │ │ │ │ -	bool in_error_code = false;
    │ │ │ │ -	bool exit = false;
    │ │ │ │ -	int error_code = -1;
    │ │ │ │ -};
    │ │ │ │ -
    │ │ │ │ -struct ip_address_parse_state: error_code_parse_state
    │ │ │ │ -{
    │ │ │ │ -	bool in_ip_address = false;
    │ │ │ │ -	std::string ip_address;
    │ │ │ │ -};
    │ │ │ │ -
    │ │ │ │ -TORRENT_EXTRA_EXPORT void find_control_url(int type, string_view, parse_state& state);
    │ │ │ │ -
    │ │ │ │ -TORRENT_EXTRA_EXPORT void find_error_code(int type, string_view string
    │ │ │ │ -	, error_code_parse_state& state);
    │ │ │ │ -
    │ │ │ │ -TORRENT_EXTRA_EXPORT void find_ip_address(int type, string_view string
    │ │ │ │ -	, ip_address_parse_state& state);
    │ │ │ │ -
    │ │ │ │ -
    struct TORRENT_EXTRA_EXPORT upnp final │ │ │ │ -
    : std::enable_shared_from_this<upnp> │ │ │ │ - , single_threaded │ │ │ │ -{ │ │ │ │ - upnp(io_context& ios │ │ │ │ - , aux::session_settings const& settings │ │ │ │ - , aux::portmap_callback& cb │ │ │ │ - , address_v4 listen_address │ │ │ │ - , address_v4 netmask │ │ │ │ - , std::string listen_device │ │ │ │ - , aux::listen_socket_handle ls); │ │ │ │ - ~upnp(); │ │ │ │ - │ │ │ │ - void start(); │ │ │ │ - │ │ │ │ - // Attempts to add a port mapping for the specified protocol. Valid protocols are │ │ │ │ - // ``upnp::tcp`` and ``upnp::udp`` for the UPnP class and ``natpmp::tcp`` and │ │ │ │ - // ``natpmp::udp`` for the NAT-PMP class. │ │ │ │ - // │ │ │ │ - // ``external_port`` is the port on the external address that will be mapped. This │ │ │ │ - // is a hint, you are not guaranteed that this port will be available, and it may │ │ │ │ - // end up being something else. In the portmap_alert_ notification, the actual │ │ │ │ - // external port is reported. │ │ │ │ - // │ │ │ │ - // ``local_port`` is the port in the local machine that the mapping should forward │ │ │ │ - // to. │ │ │ │ - // │ │ │ │ - // The return value is an index that identifies this port mapping. This is used │ │ │ │ - // to refer to mappings that fails or succeeds in the portmap_error_alert_ and │ │ │ │ - // portmap_alert_ respectively. If The mapping fails immediately, the return value │ │ │ │ - // is -1, which means failure. There will not be any error alert notification for │ │ │ │ -
    relevance 0../include/libtorrent/performance_counters.hpp:485some space could be saved here by making gauges 32 bits

    some space could be saved here by making gauges 32 bits

    ../include/libtorrent/performance_counters.hpp:485

    relevance 0../include/libtorrent/performance_counters.hpp:486restore these to regular integers. Instead have one copy of the counters per thread and collect them at convenient synchronization points

    restore these to regular integers. Instead have one copy │ │ │ │ -of the counters per thread and collect them at convenient │ │ │ │ -synchronization points

    ../include/libtorrent/performance_counters.hpp:486

    #ifdef ATOMIC_LLONG_LOCK_FREE
    │ │ │ │ -#define TORRENT_COUNTER_NOEXCEPT noexcept
    │ │ │ │ -#else
    │ │ │ │ -#define TORRENT_COUNTER_NOEXCEPT
    │ │ │ │ -#endif
    │ │ │ │ -
    │ │ │ │ -		counters() TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -
    │ │ │ │ -		counters(counters const&) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -		counters& operator=(counters const&) & TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -
    │ │ │ │ -		// returns the new value
    │ │ │ │ -		std::int64_t inc_stats_counter(int c, std::int64_t value = 1) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -		std::int64_t operator[](int i) const TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -
    │ │ │ │ -		void set_value(int c, std::int64_t value) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -		void blend_stats_counter(int c, std::int64_t value, int ratio) TORRENT_COUNTER_NOEXCEPT;
    │ │ │ │ -
    │ │ │ │ -	private:
    │ │ │ │ -
    │ │ │ │ -
    #ifdef ATOMIC_LLONG_LOCK_FREE │ │ │ │ -
    aux::array<std::atomic<std::int64_t>, num_counters> m_stats_counter; │ │ │ │ -#else │ │ │ │ - // if the atomic type isn't lock-free, use a single lock instead, for │ │ │ │ - // the whole array │ │ │ │ - mutable std::mutex m_mutex; │ │ │ │ - aux::array<std::int64_t, num_counters> m_stats_counter; │ │ │ │ -#endif │ │ │ │ - }; │ │ │ │ -} │ │ │ │ - │ │ │ │ -#endif │ │ │ │
    relevance 0../include/libtorrent/kademlia/msg.hpp:87move this to its own .hpp/.cpp pair?

    move this to its own .hpp/.cpp pair?

    ../include/libtorrent/kademlia/msg.hpp:87

    	int flags;
    │ │ │ │  
    │ │ │ │  	enum {
    │ │ │ │  		// this argument is optional, parsing will not
    │ │ │ │  		// fail if it's not present
    │ │ │ │  		optional = 1,
    │ │ │ │  		// for dictionaries, the following entries refer
    │ │ │ │ @@ -11468,306 +11468,56 @@
    │ │ │ │  		, secret_key const& sk);
    │ │ │ │  	explicit item(bdecode_node const& v);
    │ │ │ │  
    │ │ │ │  	void assign(entry v);
    │ │ │ │  	void assign(entry v, span<char const> salt
    │ │ │ │  		, sequence_number seq
    │ │ │ │  		, public_key const& pk
    │ │ │ │ -
    relevance 0../include/libtorrent/aux_/session_interface.hpp:212it would be nice to not have this be part of session_interface

    it would be nice to not have this be part of session_interface

    ../include/libtorrent/aux_/session_interface.hpp:212

    		virtual void deferred_submit_jobs() = 0;
    │ │ │ │ -
    │ │ │ │ -		virtual std::uint16_t listen_port() const = 0;
    │ │ │ │ -		virtual std::uint16_t ssl_listen_port() const = 0;
    │ │ │ │ -
    │ │ │ │ -		virtual int listen_port(aux::transport ssl, address const& local_addr) = 0;
    │ │ │ │ -
    │ │ │ │ -		virtual void for_each_listen_socket(std::function<void(aux::listen_socket_handle const&)> f) = 0;
    │ │ │ │ -
    │ │ │ │ -		// ask for which interface and port to bind outgoing peer connections on
    │ │ │ │ -		virtual tcp::endpoint bind_outgoing_socket(socket_type& s, address const&
    │ │ │ │ -			remote_address, error_code& ec) const = 0;
    │ │ │ │ -		virtual bool verify_bound_address(address const& addr, bool utp
    │ │ │ │ -			, error_code& ec) = 0;
    │ │ │ │ -
    │ │ │ │ -#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS
    │ │ │ │ -		virtual std::vector<std::shared_ptr<torrent>> find_collection(
    │ │ │ │ -			std::string const& collection) const = 0;
    │ │ │ │ -#endif
    │ │ │ │ -
    │ │ │ │ -
    virtual proxy_settings proxy() const = 0; │ │ │ │ -
    │ │ │ │ -#if TORRENT_USE_I2P │ │ │ │ - virtual char const* i2p_session() const = 0; │ │ │ │ - virtual std::string const& local_i2p_endpoint() const = 0; │ │ │ │ -#endif │ │ │ │ - │ │ │ │ - virtual void prioritize_connections(std::weak_ptr<torrent> t) = 0; │ │ │ │ - │ │ │ │ - virtual void trigger_auto_manage() = 0; │ │ │ │ - │ │ │ │ - virtual void apply_settings_pack(std::shared_ptr<settings_pack> pack) = 0; │ │ │ │ - virtual session_settings const& settings() const = 0; │ │ │ │ - │ │ │ │ - virtual void queue_tracker_request(tracker_request req │ │ │ │ - , std::weak_ptr<request_callback> c) = 0; │ │ │ │ - │ │ │ │ - // peer-classes │ │ │ │ - virtual void set_peer_classes(peer_class_set* s, address const& a, socket_type_t st) = 0; │ │ │ │ - virtual peer_class_pool const& peer_classes() const = 0; │ │ │ │ - virtual peer_class_pool& peer_classes() = 0; │ │ │ │ - virtual bool ignore_unchoke_slots_set(peer_class_set const& set) const = 0; │ │ │ │ - virtual int copy_pertinent_channels(peer_class_set const& set │ │ │ │ - , int channel, bandwidth_channel** dst, int m) = 0; │ │ │ │ - virtual int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) = 0; │ │ │ │ - │ │ │ │ - virtual bandwidth_manager* get_bandwidth_manager(int channel) = 0; │ │ │ │ - │ │ │ │ - virtual void sent_bytes(int bytes_payload, int bytes_protocol) = 0; │ │ │ │ - virtual void received_bytes(int bytes_payload, int bytes_protocol) = 0; │ │ │ │ - virtual void trancieve_ip_packet(int bytes, bool ipv6) = 0; │ │ │ │ -
    relevance 0../include/libtorrent/aux_/session_impl.hpp:265make these direct members and generate shared_ptrs to them which alias the listen_socket_t shared_ptr

    make these direct members and generate shared_ptrs to them │ │ │ │ -which alias the listen_socket_t shared_ptr

    ../include/libtorrent/aux_/session_impl.hpp:265

    			if (udp_sock) return udp_sock->sock.local_port();
    │ │ │ │ -			return 0;
    │ │ │ │ -		}
    │ │ │ │ -
    │ │ │ │ -		// 0 is natpmp 1 is upnp
    │ │ │ │ -		// the order of these arrays determines the priority in
    │ │ │ │ -		// which their ports will be announced to peers
    │ │ │ │ -		aux::array<listen_port_mapping, 2, portmap_transport> tcp_port_mapping;
    │ │ │ │ -		aux::array<listen_port_mapping, 2, portmap_transport> udp_port_mapping;
    │ │ │ │ -
    │ │ │ │ -		// indicates whether this is an SSL listen socket or not
    │ │ │ │ -		transport ssl = transport::plaintext;
    │ │ │ │ -
    │ │ │ │ -		listen_socket_flags_t flags = accept_incoming;
    │ │ │ │ -
    │ │ │ │ -		// the actual sockets (TCP listen socket and UDP socket)
    │ │ │ │ -		// An entry does not necessarily have a UDP or TCP socket. One of these
    │ │ │ │ -		// pointers may be nullptr!
    │ │ │ │ -		// These must be shared_ptr to avoid a dangling reference if an
    │ │ │ │ -		// incoming packet is in the event queue when the socket is erased
    │ │ │ │ -
    std::shared_ptr<tcp::acceptor> sock; │ │ │ │ -
    std::shared_ptr<aux::session_udp_socket> udp_sock; │ │ │ │ - │ │ │ │ - // since udp packets are expected to be dispatched frequently, this saves │ │ │ │ - // time on handler allocation every time we read again. │ │ │ │ - aux::handler_storage<aux::udp_handler_max_size, aux::udp_handler> udp_handler_storage; │ │ │ │ - │ │ │ │ - std::shared_ptr<natpmp> natpmp_mapper; │ │ │ │ - std::shared_ptr<upnp> upnp_mapper; │ │ │ │ - │ │ │ │ - std::shared_ptr<struct lsd> lsd; │ │ │ │ +
    relevance 0../include/libtorrent/aux_/deprecated.hpp:47figure out which version of clang this is supported in

    figure out which version of clang this is supported in

    ../include/libtorrent/aux_/deprecated.hpp:47

    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    │ │ │ │ +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    │ │ │ │ +POSSIBILITY OF SUCH DAMAGE.
    │ │ │ │  
    │ │ │ │ -		// set to true when we receive an incoming connection from this listen
    │ │ │ │ -		// socket
    │ │ │ │ -		bool incoming_connection = false;
    │ │ │ │ -	};
    │ │ │ │ +*/
    │ │ │ │  
    │ │ │ │ -		struct TORRENT_EXTRA_EXPORT listen_endpoint_t
    │ │ │ │ -		{
    │ │ │ │ -			listen_endpoint_t(address const& adr, int p, std::string dev, transport s
    │ │ │ │ -				, listen_socket_flags_t f, address const& nmask = address{})
    │ │ │ │ -				: addr(adr), netmask(nmask), port(p), device(std::move(dev)), ssl(s), flags(f) {}
    │ │ │ │ +#ifndef TORRENT_DEPRECATED_HPP_INCLUDED
    │ │ │ │ +#define TORRENT_DEPRECATED_HPP_INCLUDED
    │ │ │ │  
    │ │ │ │ -			bool operator==(listen_endpoint_t const& o) const
    │ │ │ │ -			{
    │ │ │ │ -				return addr == o.addr
    │ │ │ │ -					&& port == o.port
    │ │ │ │ -					&& device == o.device
    │ │ │ │ -					&& ssl == o.ssl
    │ │ │ │ -					&& flags == o.flags;
    │ │ │ │ -			}
    │ │ │ │ -
    relevance 0../include/libtorrent/aux_/session_impl.hpp:1068replace this by a proper asio timer

    replace this by a proper asio timer

    ../include/libtorrent/aux_/session_impl.hpp:1068

    #ifdef TORRENT_SSL_PEERS
    │ │ │ │ -			void on_incoming_utp_ssl(socket_type s);
    │ │ │ │ -			void ssl_handshake(error_code const& ec, socket_type* s);
    │ │ │ │ +#if !defined TORRENT_BUILDING_LIBRARY
    │ │ │ │ +# define TORRENT_DEPRECATED [[deprecated]]
    │ │ │ │ +#else
    │ │ │ │ +# define TORRENT_DEPRECATED
    │ │ │ │  #endif
    │ │ │ │  
    │ │ │ │ -			// round-robin index into m_outgoing_interfaces
    │ │ │ │ -			mutable std::uint8_t m_interface_index = 0;
    │ │ │ │ -
    │ │ │ │ -			std::shared_ptr<listen_socket_t> setup_listener(
    │ │ │ │ -				listen_endpoint_t const& lep, error_code& ec);
    │ │ │ │ +#if defined __clang__
    │ │ │ │  
    │ │ │ │ -#ifndef TORRENT_DISABLE_DHT
    │ │ │ │ -			dht::dht_state m_dht_state;
    │ │ │ │ -#endif
    │ │ │ │ +// ====== CLANG ========
    │ │ │ │  
    │ │ │ │ -			// this is initialized to the unchoke_interval
    │ │ │ │ -			// session_setting and decreased every second.
    │ │ │ │ -			// when it reaches zero, it is reset to the
    │ │ │ │ -			// unchoke_interval and the unchoke set is
    │ │ │ │ -			// recomputed.
    │ │ │ │ -
    int m_unchoke_time_scaler = 0; │ │ │ │ -
    │ │ │ │ - // this is used to decide when to recalculate which │ │ │ │ - // torrents to keep queued and which to activate │ │ │ │ -
    relevance 0../include/libtorrent/aux_/session_impl.hpp:1073replace this by a proper asio timer

    replace this by a proper asio timer

    ../include/libtorrent/aux_/session_impl.hpp:1073

    │ │ │ │ -			// round-robin index into m_outgoing_interfaces
    │ │ │ │ -			mutable std::uint8_t m_interface_index = 0;
    │ │ │ │ +# if !defined TORRENT_BUILDING_LIBRARY
    │ │ │ │ +
    # define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) │ │ │ │ +
    # endif │ │ │ │ │ │ │ │ - std::shared_ptr<listen_socket_t> setup_listener( │ │ │ │ - listen_endpoint_t const& lep, error_code& ec); │ │ │ │ +#elif defined __GNUC__ │ │ │ │ │ │ │ │ -#ifndef TORRENT_DISABLE_DHT │ │ │ │ - dht::dht_state m_dht_state; │ │ │ │ -#endif │ │ │ │ +// ======== GCC ======== │ │ │ │ │ │ │ │ - // this is initialized to the unchoke_interval │ │ │ │ - // session_setting and decreased every second. │ │ │ │ - // when it reaches zero, it is reset to the │ │ │ │ - // unchoke_interval and the unchoke set is │ │ │ │ - // recomputed. │ │ │ │ - int m_unchoke_time_scaler = 0; │ │ │ │ +// deprecation markup is only enabled when libtorrent │ │ │ │ +// headers are included by clients, not while building │ │ │ │ +// libtorrent itself │ │ │ │ +# if __GNUC__ >= 6 && !defined TORRENT_BUILDING_LIBRARY │ │ │ │ +# define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) │ │ │ │ +# endif │ │ │ │ │ │ │ │ - // this is used to decide when to recalculate which │ │ │ │ - // torrents to keep queued and which to activate │ │ │ │ -
    int m_auto_manage_time_scaler = 0; │ │ │ │ -
    │ │ │ │ - // works like unchoke_time_scaler but it │ │ │ │ - // is only decreased when the unchoke set │ │ │ │ - // is recomputed, and when it reaches zero, │ │ │ │ - // the optimistic unchoke is moved to another peer. │ │ │ │ -
    relevance 0../include/libtorrent/aux_/session_impl.hpp:1080replace this by a proper asio timer

    replace this by a proper asio timer

    ../include/libtorrent/aux_/session_impl.hpp:1080

    │ │ │ │ -#ifndef TORRENT_DISABLE_DHT
    │ │ │ │ -			dht::dht_state m_dht_state;
    │ │ │ │  #endif
    │ │ │ │  
    │ │ │ │ -			// this is initialized to the unchoke_interval
    │ │ │ │ -			// session_setting and decreased every second.
    │ │ │ │ -			// when it reaches zero, it is reset to the
    │ │ │ │ -			// unchoke_interval and the unchoke set is
    │ │ │ │ -			// recomputed.
    │ │ │ │ -			int m_unchoke_time_scaler = 0;
    │ │ │ │ -
    │ │ │ │ -			// this is used to decide when to recalculate which
    │ │ │ │ -			// torrents to keep queued and which to activate
    │ │ │ │ -			int m_auto_manage_time_scaler = 0;
    │ │ │ │ -
    │ │ │ │ -			// works like unchoke_time_scaler but it
    │ │ │ │ -			// is only decreased when the unchoke set
    │ │ │ │ -			// is recomputed, and when it reaches zero,
    │ │ │ │ -			// the optimistic unchoke is moved to another peer.
    │ │ │ │ -
    int m_optimistic_unchoke_time_scaler = 0; │ │ │ │ -
    │ │ │ │ - // works like unchoke_time_scaler. Each time │ │ │ │ - // it reaches 0, and all the connections are │ │ │ │ - // used, the worst connection will be disconnected │ │ │ │ - // from the torrent with the most peers │ │ │ │ - int m_disconnect_time_scaler = 90; │ │ │ │ - │ │ │ │ - // when this scaler reaches zero, it will │ │ │ │ - // scrape one of the auto managed, paused, │ │ │ │ - // torrents. │ │ │ │ - int m_auto_scrape_time_scaler = 180; │ │ │ │ - │ │ │ │ - // statistics gathered from all torrents. │ │ │ │ - stat m_stat; │ │ │ │ - │ │ │ │ - // implements session_interface │ │ │ │ - void sent_bytes(int bytes_payload, int bytes_protocol) override; │ │ │ │ - void received_bytes(int bytes_payload, int bytes_protocol) override; │ │ │ │ - void trancieve_ip_packet(int bytes, bool ipv6) override; │ │ │ │ - void sent_syn(bool ipv6) override; │ │ │ │ - void received_synack(bool ipv6) override; │ │ │ │ - │ │ │ │ -#if TORRENT_ABI_VERSION == 1 │ │ │ │ - int m_peak_up_rate = 0; │ │ │ │ +#ifndef TORRENT_DEPRECATED_ENUM │ │ │ │ +#define TORRENT_DEPRECATED_ENUM │ │ │ │ #endif │ │ │ │ │ │ │ │ - void on_tick(error_code const& e); │ │ │ │ - │ │ │ │ - void try_connect_more_peers(); │ │ │ │ - void auto_manage_checking_torrents(std::vector<torrent*>& list │ │ │ │ -
    relevance 0../include/libtorrent/aux_/announce_entry.hpp:74include the number of peers received from this tracker, at last announce

    include the number of peers received from this tracker, at last │ │ │ │ -announce

    ../include/libtorrent/aux_/announce_entry.hpp:74

    namespace aux {
    │ │ │ │ -
    │ │ │ │ -	struct TORRENT_EXTRA_EXPORT announce_infohash
    │ │ │ │ -	{
    │ │ │ │ -		announce_infohash();
    │ │ │ │ -
    │ │ │ │ -		// if this tracker has returned an error or warning message
    │ │ │ │ -		// that message is stored here
    │ │ │ │ -		std::string message;
    │ │ │ │ -
    │ │ │ │ -		// if this tracker failed the last time it was contacted
    │ │ │ │ -		// this error code specifies what error occurred
    │ │ │ │ -		error_code last_error;
    │ │ │ │ -
    │ │ │ │ -		// the time of next tracker announce
    │ │ │ │ -		time_point32 next_announce = (time_point32::min)();
    │ │ │ │ -
    │ │ │ │ -		// no announces before this time
    │ │ │ │ -		time_point32 min_announce = (time_point32::min)();
    │ │ │ │ -
    │ │ │ │ -
    │ │ │ │ -
    // these are either -1 or the scrape information this tracker last │ │ │ │ - // responded with. *incomplete* is the current number of downloaders in │ │ │ │ - // the swarm, *complete* is the current number of seeds in the swarm and │ │ │ │ - // *downloaded* is the cumulative number of completed downloads of this │ │ │ │ - // torrent, since the beginning of time (from this tracker's point of │ │ │ │ - // view). │ │ │ │ - │ │ │ │ - // if this tracker has returned scrape data, these fields are filled in │ │ │ │ - // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts │ │ │ │ - // the number of current downloaders. ``complete`` counts the number of │ │ │ │ - // current peers completed the download, or "seeds". ``downloaded`` is the │ │ │ │ - // cumulative number of completed downloads. │ │ │ │ - int scrape_incomplete = -1; │ │ │ │ - int scrape_complete = -1; │ │ │ │ - int scrape_downloaded = -1; │ │ │ │ - │ │ │ │ - // the number of times in a row we have failed to announce to this │ │ │ │ - // tracker. │ │ │ │ - std::uint8_t fails : 7; │ │ │ │ - │ │ │ │ - // true while we're waiting for a response from the tracker. │ │ │ │ - bool updating : 1; │ │ │ │ - │ │ │ │ - // set to true when we get a valid response from an announce │ │ │ │ - // with event=started. If it is set, we won't send start in the subsequent │ │ │ │ - // announces. │ │ │ │ - bool start_sent : 1; │ │ │ │ - │ │ │ │ - // set to true when we send a event=completed. │ │ │ │ - bool complete_sent : 1; │ │ │ │ -
    relevance 0../include/libtorrent/aux_/pool.hpp:49ensure the alignment is good here

    ensure the alignment is good here

    ../include/libtorrent/aux_/pool.hpp:49

    POSSIBILITY OF SUCH DAMAGE.
    │ │ │ │ -
    │ │ │ │ -*/
    │ │ │ │ -
    │ │ │ │ -#ifndef TORRENT_POOL_HPP
    │ │ │ │ -#define TORRENT_POOL_HPP
    │ │ │ │ -
    │ │ │ │ -#include "libtorrent/aux_/disable_warnings_push.hpp"
    │ │ │ │ -#include <boost/pool/pool.hpp>
    │ │ │ │ -#include <boost/pool/object_pool.hpp>
    │ │ │ │ -#include "libtorrent/aux_/disable_warnings_pop.hpp"
    │ │ │ │ -
    │ │ │ │ -namespace libtorrent {
    │ │ │ │ -namespace aux {
    │ │ │ │ -
    │ │ │ │ -struct allocator_new_delete
    │ │ │ │ -{
    │ │ │ │ -	using size_type = std::size_t;
    │ │ │ │ -	using difference_type = std::ptrdiff_t;
    │ │ │ │ -
    │ │ │ │ -
    static char* malloc(size_type const bytes) │ │ │ │ -
    { return new char[bytes]; } │ │ │ │ - static void free(char* const block) │ │ │ │ - { delete [] block; } │ │ │ │ -}; │ │ │ │ - │ │ │ │ -using pool = boost::pool<allocator_new_delete>; │ │ │ │ - │ │ │ │ -template <typename T> │ │ │ │ -using object_pool = boost::object_pool<T, allocator_new_delete>; │ │ │ │ - │ │ │ │ -} │ │ │ │ -} │ │ │ │ - │ │ │ │ #endif │ │ │ │ -
    relevance 0../include/libtorrent/aux_/merkle_tree.hpp:85remove this constructor. Don't support "uninitialized" trees. This also requires not constructing these for pad-files and small files as well. So, a sparse hash list in torrent_info

    remove this constructor. Don't support "uninitialized" trees. This │ │ │ │ +relevance 0../include/libtorrent/aux_/merkle_tree.hpp:85remove this constructor. Don't support "uninitialized" trees. This also requires not constructing these for pad-files and small files as well. So, a sparse hash list in torrent_info

    remove this constructor. Don't support "uninitialized" trees. This │ │ │ │ also requires not constructing these for pad-files and small files as │ │ │ │ well. So, a sparse hash list in torrent_info

    ../include/libtorrent/aux_/merkle_tree.hpp:85

    // The invariant of the tree is that all interior nodes (i.e. all but the very
    │ │ │ │  // bottom leaf nodes, representing block hashes) are either set and valid, or
    │ │ │ │  // clear. No invalid hashes are allowed, and they can only be added by also
    │ │ │ │  // providing proof of being valid.
    │ │ │ │  
    │ │ │ │  // The leaf blocks on the other hand, MAY be invalid. For instance, when adding
    │ │ │ │ @@ -11812,15 +11562,15 @@
    │ │ │ │  
    │ │ │ │  	// returns true if the entire tree is known and verified
    │ │ │ │  	bool is_complete() const;
    │ │ │ │  
    │ │ │ │  	// returns true if all block hashes in the specified range have been verified
    │ │ │ │  	bool blocks_verified(int block_idx, int num_blocks) const;
    │ │ │ │  
    │ │ │ │ -
    relevance 0../include/libtorrent/aux_/merkle_tree.hpp:175make this a std::unique_ptr

    make this a std::unique_ptr

    ../include/libtorrent/aux_/merkle_tree.hpp:175

    │ │ │ │ +
    relevance 0../include/libtorrent/aux_/merkle_tree.hpp:175make this a std::unique_ptr

    make this a std::unique_ptr

    ../include/libtorrent/aux_/merkle_tree.hpp:175

    │ │ │ │  	int blocks_per_piece() const { return 1 << m_blocks_per_piece_log; }
    │ │ │ │  	// the number tree levels per piece. This is 0 if the block layer is also
    │ │ │ │  	// the piece layer.
    │ │ │ │  	int piece_levels() const { return m_blocks_per_piece_log; }
    │ │ │ │  
    │ │ │ │  	int block_layer_start() const;
    │ │ │ │  	int piece_layer_start() const;
    │ │ │ │ @@ -11863,56 +11613,102 @@
    │ │ │ │  		// we don't have any hashes in this tree. m_tree should be empty
    │ │ │ │  		// an empty tree still always have the root hash (available as root())
    │ │ │ │  		empty_tree,
    │ │ │ │  
    │ │ │ │  		// in this mode, m_tree represents the full tree, including padding.
    │ │ │ │  		full_tree,
    │ │ │ │  
    │ │ │ │ -
    relevance 0../include/libtorrent/aux_/deprecated.hpp:47figure out which version of clang this is supported in

    figure out which version of clang this is supported in

    ../include/libtorrent/aux_/deprecated.hpp:47

    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    │ │ │ │ -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    │ │ │ │ -POSSIBILITY OF SUCH DAMAGE.
    │ │ │ │ +
    relevance 0../include/libtorrent/aux_/announce_entry.hpp:74include the number of peers received from this tracker, at last announce

    include the number of peers received from this tracker, at last │ │ │ │ +announce

    ../include/libtorrent/aux_/announce_entry.hpp:74

    namespace aux {
    │ │ │ │  
    │ │ │ │ -*/
    │ │ │ │ +	struct TORRENT_EXTRA_EXPORT announce_infohash
    │ │ │ │ +	{
    │ │ │ │ +		announce_infohash();
    │ │ │ │  
    │ │ │ │ -#ifndef TORRENT_DEPRECATED_HPP_INCLUDED
    │ │ │ │ -#define TORRENT_DEPRECATED_HPP_INCLUDED
    │ │ │ │ +		// if this tracker has returned an error or warning message
    │ │ │ │ +		// that message is stored here
    │ │ │ │ +		std::string message;
    │ │ │ │  
    │ │ │ │ -#if !defined TORRENT_BUILDING_LIBRARY
    │ │ │ │ -# define TORRENT_DEPRECATED [[deprecated]]
    │ │ │ │ -#else
    │ │ │ │ -# define TORRENT_DEPRECATED
    │ │ │ │ -#endif
    │ │ │ │ +		// if this tracker failed the last time it was contacted
    │ │ │ │ +		// this error code specifies what error occurred
    │ │ │ │ +		error_code last_error;
    │ │ │ │  
    │ │ │ │ -#if defined __clang__
    │ │ │ │ +		// the time of next tracker announce
    │ │ │ │ +		time_point32 next_announce = (time_point32::min)();
    │ │ │ │  
    │ │ │ │ -// ====== CLANG ========
    │ │ │ │ +		// no announces before this time
    │ │ │ │ +		time_point32 min_announce = (time_point32::min)();
    │ │ │ │  
    │ │ │ │ -# if !defined TORRENT_BUILDING_LIBRARY
    │ │ │ │ -
    # define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) │ │ │ │ -
    # endif │ │ │ │ +
    │ │ │ │ +
    // these are either -1 or the scrape information this tracker last │ │ │ │ + // responded with. *incomplete* is the current number of downloaders in │ │ │ │ + // the swarm, *complete* is the current number of seeds in the swarm and │ │ │ │ + // *downloaded* is the cumulative number of completed downloads of this │ │ │ │ + // torrent, since the beginning of time (from this tracker's point of │ │ │ │ + // view). │ │ │ │ │ │ │ │ -#elif defined __GNUC__ │ │ │ │ + // if this tracker has returned scrape data, these fields are filled in │ │ │ │ + // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts │ │ │ │ + // the number of current downloaders. ``complete`` counts the number of │ │ │ │ + // current peers completed the download, or "seeds". ``downloaded`` is the │ │ │ │ + // cumulative number of completed downloads. │ │ │ │ + int scrape_incomplete = -1; │ │ │ │ + int scrape_complete = -1; │ │ │ │ + int scrape_downloaded = -1; │ │ │ │ │ │ │ │ -// ======== GCC ======== │ │ │ │ + // the number of times in a row we have failed to announce to this │ │ │ │ + // tracker. │ │ │ │ + std::uint8_t fails : 7; │ │ │ │ │ │ │ │ -// deprecation markup is only enabled when libtorrent │ │ │ │ -// headers are included by clients, not while building │ │ │ │ -// libtorrent itself │ │ │ │ -# if __GNUC__ >= 6 && !defined TORRENT_BUILDING_LIBRARY │ │ │ │ -# define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) │ │ │ │ -# endif │ │ │ │ + // true while we're waiting for a response from the tracker. │ │ │ │ + bool updating : 1; │ │ │ │ │ │ │ │ -#endif │ │ │ │ + // set to true when we get a valid response from an announce │ │ │ │ + // with event=started. If it is set, we won't send start in the subsequent │ │ │ │ + // announces. │ │ │ │ + bool start_sent : 1; │ │ │ │ │ │ │ │ -#ifndef TORRENT_DEPRECATED_ENUM │ │ │ │ -#define TORRENT_DEPRECATED_ENUM │ │ │ │ -#endif │ │ │ │ + // set to true when we send a event=completed. │ │ │ │ + bool complete_sent : 1; │ │ │ │ +
    relevance 0../include/libtorrent/aux_/pool.hpp:49ensure the alignment is good here

    ensure the alignment is good here

    ../include/libtorrent/aux_/pool.hpp:49

    POSSIBILITY OF SUCH DAMAGE.
    │ │ │ │ +
    │ │ │ │ +*/
    │ │ │ │ +
    │ │ │ │ +#ifndef TORRENT_POOL_HPP
    │ │ │ │ +#define TORRENT_POOL_HPP
    │ │ │ │ +
    │ │ │ │ +#include "libtorrent/aux_/disable_warnings_push.hpp"
    │ │ │ │ +#include <boost/pool/pool.hpp>
    │ │ │ │ +#include <boost/pool/object_pool.hpp>
    │ │ │ │ +#include "libtorrent/aux_/disable_warnings_pop.hpp"
    │ │ │ │ +
    │ │ │ │ +namespace libtorrent {
    │ │ │ │ +namespace aux {
    │ │ │ │ +
    │ │ │ │ +struct allocator_new_delete
    │ │ │ │ +{
    │ │ │ │ +	using size_type = std::size_t;
    │ │ │ │ +	using difference_type = std::ptrdiff_t;
    │ │ │ │ +
    │ │ │ │ +
    static char* malloc(size_type const bytes) │ │ │ │ +
    { return new char[bytes]; } │ │ │ │ + static void free(char* const block) │ │ │ │ + { delete [] block; } │ │ │ │ +}; │ │ │ │ + │ │ │ │ +using pool = boost::pool<allocator_new_delete>; │ │ │ │ + │ │ │ │ +template <typename T> │ │ │ │ +using object_pool = boost::object_pool<T, allocator_new_delete>; │ │ │ │ + │ │ │ │ +} │ │ │ │ +} │ │ │ │ │ │ │ │ #endif │ │ │ │ -
    relevance 0../include/libtorrent/aux_/allocating_handler.hpp:316in C++17, Handler and Storage could just use "auto"

    in C++17, Handler and Storage could just use "auto"

    ../include/libtorrent/aux_/allocating_handler.hpp:316

    │ │ │ │ +
    relevance 0../include/libtorrent/aux_/allocating_handler.hpp:316in C++17, Handler and Storage could just use "auto"

    in C++17, Handler and Storage could just use "auto"

    ../include/libtorrent/aux_/allocating_handler.hpp:316

    │ │ │ │  	private:
    │ │ │ │  
    │ │ │ │  		Handler handler;
    │ │ │ │  		handler_storage<Size, Name>* storage;
    │ │ │ │  #ifndef BOOST_NO_EXCEPTIONS
    │ │ │ │  		error_handler_interface* error_handler;
    │ │ │ │  #endif
    │ │ │ │ @@ -11955,15 +11751,15 @@
    │ │ │ │  			{
    │ │ │ │  				(ptr_.get()->*ErrorHandler)(e.code());
    │ │ │ │  			}
    │ │ │ │  			catch (std::exception const& e)
    │ │ │ │  			{
    │ │ │ │  				(ptr_.get()->*ExceptHandler)(e);
    │ │ │ │  			}
    │ │ │ │ -
    relevance 0../include/libtorrent/aux_/utp_stream.hpp:693it would be nice to make this private

    it would be nice to make this private

    ../include/libtorrent/aux_/utp_stream.hpp:693

    	bool consume_incoming_data(
    │ │ │ │ +
    relevance 0../include/libtorrent/aux_/utp_stream.hpp:693it would be nice to make this private

    it would be nice to make this private

    ../include/libtorrent/aux_/utp_stream.hpp:693

    	bool consume_incoming_data(
    │ │ │ │  		utp_header const* ph, std::uint8_t const* ptr, int payload_size, time_point now);
    │ │ │ │  	void update_mtu_limits();
    │ │ │ │  	void experienced_loss(std::uint32_t seq_nr, time_point now);
    │ │ │ │  
    │ │ │ │  	void send_deferred_ack();
    │ │ │ │  	void socket_drained();
    │ │ │ │  
    │ │ │ │ @@ -12006,8 +11802,212 @@
    │ │ │ │  	// it's important that these match the enums in performance_counters for
    │ │ │ │  	// num_utp_idle etc.
    │ │ │ │  	enum class state_t {
    │ │ │ │  		// not yet connected
    │ │ │ │  		none,
    │ │ │ │  		// sent a syn packet, not received any acks
    │ │ │ │  		syn_sent,
    │ │ │ │ +
    relevance 0../include/libtorrent/aux_/session_impl.hpp:265make these direct members and generate shared_ptrs to them which alias the listen_socket_t shared_ptr

    make these direct members and generate shared_ptrs to them │ │ │ │ +which alias the listen_socket_t shared_ptr

    ../include/libtorrent/aux_/session_impl.hpp:265

    			if (udp_sock) return udp_sock->sock.local_port();
    │ │ │ │ +			return 0;
    │ │ │ │ +		}
    │ │ │ │ +
    │ │ │ │ +		// 0 is natpmp 1 is upnp
    │ │ │ │ +		// the order of these arrays determines the priority in
    │ │ │ │ +		// which their ports will be announced to peers
    │ │ │ │ +		aux::array<listen_port_mapping, 2, portmap_transport> tcp_port_mapping;
    │ │ │ │ +		aux::array<listen_port_mapping, 2, portmap_transport> udp_port_mapping;
    │ │ │ │ +
    │ │ │ │ +		// indicates whether this is an SSL listen socket or not
    │ │ │ │ +		transport ssl = transport::plaintext;
    │ │ │ │ +
    │ │ │ │ +		listen_socket_flags_t flags = accept_incoming;
    │ │ │ │ +
    │ │ │ │ +		// the actual sockets (TCP listen socket and UDP socket)
    │ │ │ │ +		// An entry does not necessarily have a UDP or TCP socket. One of these
    │ │ │ │ +		// pointers may be nullptr!
    │ │ │ │ +		// These must be shared_ptr to avoid a dangling reference if an
    │ │ │ │ +		// incoming packet is in the event queue when the socket is erased
    │ │ │ │ +
    std::shared_ptr<tcp::acceptor> sock; │ │ │ │ +
    std::shared_ptr<aux::session_udp_socket> udp_sock; │ │ │ │ + │ │ │ │ + // since udp packets are expected to be dispatched frequently, this saves │ │ │ │ + // time on handler allocation every time we read again. │ │ │ │ + aux::handler_storage<aux::udp_handler_max_size, aux::udp_handler> udp_handler_storage; │ │ │ │ + │ │ │ │ + std::shared_ptr<natpmp> natpmp_mapper; │ │ │ │ + std::shared_ptr<upnp> upnp_mapper; │ │ │ │ + │ │ │ │ + std::shared_ptr<struct lsd> lsd; │ │ │ │ + │ │ │ │ + // set to true when we receive an incoming connection from this listen │ │ │ │ + // socket │ │ │ │ + bool incoming_connection = false; │ │ │ │ + }; │ │ │ │ + │ │ │ │ + struct TORRENT_EXTRA_EXPORT listen_endpoint_t │ │ │ │ + { │ │ │ │ + listen_endpoint_t(address const& adr, int p, std::string dev, transport s │ │ │ │ + , listen_socket_flags_t f, address const& nmask = address{}) │ │ │ │ + : addr(adr), netmask(nmask), port(p), device(std::move(dev)), ssl(s), flags(f) {} │ │ │ │ + │ │ │ │ + bool operator==(listen_endpoint_t const& o) const │ │ │ │ + { │ │ │ │ + return addr == o.addr │ │ │ │ + && port == o.port │ │ │ │ + && device == o.device │ │ │ │ + && ssl == o.ssl │ │ │ │ + && flags == o.flags; │ │ │ │ + } │ │ │ │ +
    relevance 0../include/libtorrent/aux_/session_impl.hpp:1068replace this by a proper asio timer

    replace this by a proper asio timer

    ../include/libtorrent/aux_/session_impl.hpp:1068

    #ifdef TORRENT_SSL_PEERS
    │ │ │ │ +			void on_incoming_utp_ssl(socket_type s);
    │ │ │ │ +			void ssl_handshake(error_code const& ec, socket_type* s);
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +			// round-robin index into m_outgoing_interfaces
    │ │ │ │ +			mutable std::uint8_t m_interface_index = 0;
    │ │ │ │ +
    │ │ │ │ +			std::shared_ptr<listen_socket_t> setup_listener(
    │ │ │ │ +				listen_endpoint_t const& lep, error_code& ec);
    │ │ │ │ +
    │ │ │ │ +#ifndef TORRENT_DISABLE_DHT
    │ │ │ │ +			dht::dht_state m_dht_state;
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +			// this is initialized to the unchoke_interval
    │ │ │ │ +			// session_setting and decreased every second.
    │ │ │ │ +			// when it reaches zero, it is reset to the
    │ │ │ │ +			// unchoke_interval and the unchoke set is
    │ │ │ │ +			// recomputed.
    │ │ │ │ +
    int m_unchoke_time_scaler = 0; │ │ │ │ +
    │ │ │ │ + // this is used to decide when to recalculate which │ │ │ │ + // torrents to keep queued and which to activate │ │ │ │ +
    relevance 0../include/libtorrent/aux_/session_impl.hpp:1073replace this by a proper asio timer

    replace this by a proper asio timer

    ../include/libtorrent/aux_/session_impl.hpp:1073

    │ │ │ │ +			// round-robin index into m_outgoing_interfaces
    │ │ │ │ +			mutable std::uint8_t m_interface_index = 0;
    │ │ │ │ +
    │ │ │ │ +			std::shared_ptr<listen_socket_t> setup_listener(
    │ │ │ │ +				listen_endpoint_t const& lep, error_code& ec);
    │ │ │ │ +
    │ │ │ │ +#ifndef TORRENT_DISABLE_DHT
    │ │ │ │ +			dht::dht_state m_dht_state;
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +			// this is initialized to the unchoke_interval
    │ │ │ │ +			// session_setting and decreased every second.
    │ │ │ │ +			// when it reaches zero, it is reset to the
    │ │ │ │ +			// unchoke_interval and the unchoke set is
    │ │ │ │ +			// recomputed.
    │ │ │ │ +			int m_unchoke_time_scaler = 0;
    │ │ │ │ +
    │ │ │ │ +			// this is used to decide when to recalculate which
    │ │ │ │ +			// torrents to keep queued and which to activate
    │ │ │ │ +
    int m_auto_manage_time_scaler = 0; │ │ │ │ +
    │ │ │ │ + // works like unchoke_time_scaler but it │ │ │ │ + // is only decreased when the unchoke set │ │ │ │ + // is recomputed, and when it reaches zero, │ │ │ │ + // the optimistic unchoke is moved to another peer. │ │ │ │ +
    relevance 0../include/libtorrent/aux_/session_impl.hpp:1080replace this by a proper asio timer

    replace this by a proper asio timer

    ../include/libtorrent/aux_/session_impl.hpp:1080

    │ │ │ │ +#ifndef TORRENT_DISABLE_DHT
    │ │ │ │ +			dht::dht_state m_dht_state;
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +			// this is initialized to the unchoke_interval
    │ │ │ │ +			// session_setting and decreased every second.
    │ │ │ │ +			// when it reaches zero, it is reset to the
    │ │ │ │ +			// unchoke_interval and the unchoke set is
    │ │ │ │ +			// recomputed.
    │ │ │ │ +			int m_unchoke_time_scaler = 0;
    │ │ │ │ +
    │ │ │ │ +			// this is used to decide when to recalculate which
    │ │ │ │ +			// torrents to keep queued and which to activate
    │ │ │ │ +			int m_auto_manage_time_scaler = 0;
    │ │ │ │ +
    │ │ │ │ +			// works like unchoke_time_scaler but it
    │ │ │ │ +			// is only decreased when the unchoke set
    │ │ │ │ +			// is recomputed, and when it reaches zero,
    │ │ │ │ +			// the optimistic unchoke is moved to another peer.
    │ │ │ │ +
    int m_optimistic_unchoke_time_scaler = 0; │ │ │ │ +
    │ │ │ │ + // works like unchoke_time_scaler. Each time │ │ │ │ + // it reaches 0, and all the connections are │ │ │ │ + // used, the worst connection will be disconnected │ │ │ │ + // from the torrent with the most peers │ │ │ │ + int m_disconnect_time_scaler = 90; │ │ │ │ + │ │ │ │ + // when this scaler reaches zero, it will │ │ │ │ + // scrape one of the auto managed, paused, │ │ │ │ + // torrents. │ │ │ │ + int m_auto_scrape_time_scaler = 180; │ │ │ │ + │ │ │ │ + // statistics gathered from all torrents. │ │ │ │ + stat m_stat; │ │ │ │ + │ │ │ │ + // implements session_interface │ │ │ │ + void sent_bytes(int bytes_payload, int bytes_protocol) override; │ │ │ │ + void received_bytes(int bytes_payload, int bytes_protocol) override; │ │ │ │ + void trancieve_ip_packet(int bytes, bool ipv6) override; │ │ │ │ + void sent_syn(bool ipv6) override; │ │ │ │ + void received_synack(bool ipv6) override; │ │ │ │ + │ │ │ │ +#if TORRENT_ABI_VERSION == 1 │ │ │ │ + int m_peak_up_rate = 0; │ │ │ │ +#endif │ │ │ │ + │ │ │ │ + void on_tick(error_code const& e); │ │ │ │ + │ │ │ │ + void try_connect_more_peers(); │ │ │ │ + void auto_manage_checking_torrents(std::vector<torrent*>& list │ │ │ │ +
    relevance 0../include/libtorrent/aux_/session_interface.hpp:212it would be nice to not have this be part of session_interface

    it would be nice to not have this be part of session_interface

    ../include/libtorrent/aux_/session_interface.hpp:212

    		virtual void deferred_submit_jobs() = 0;
    │ │ │ │ +
    │ │ │ │ +		virtual std::uint16_t listen_port() const = 0;
    │ │ │ │ +		virtual std::uint16_t ssl_listen_port() const = 0;
    │ │ │ │ +
    │ │ │ │ +		virtual int listen_port(aux::transport ssl, address const& local_addr) = 0;
    │ │ │ │ +
    │ │ │ │ +		virtual void for_each_listen_socket(std::function<void(aux::listen_socket_handle const&)> f) = 0;
    │ │ │ │ +
    │ │ │ │ +		// ask for which interface and port to bind outgoing peer connections on
    │ │ │ │ +		virtual tcp::endpoint bind_outgoing_socket(socket_type& s, address const&
    │ │ │ │ +			remote_address, error_code& ec) const = 0;
    │ │ │ │ +		virtual bool verify_bound_address(address const& addr, bool utp
    │ │ │ │ +			, error_code& ec) = 0;
    │ │ │ │ +
    │ │ │ │ +#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS
    │ │ │ │ +		virtual std::vector<std::shared_ptr<torrent>> find_collection(
    │ │ │ │ +			std::string const& collection) const = 0;
    │ │ │ │ +#endif
    │ │ │ │ +
    │ │ │ │ +
    virtual proxy_settings proxy() const = 0; │ │ │ │ +
    │ │ │ │ +#if TORRENT_USE_I2P │ │ │ │ + virtual char const* i2p_session() const = 0; │ │ │ │ + virtual std::string const& local_i2p_endpoint() const = 0; │ │ │ │ +#endif │ │ │ │ + │ │ │ │ + virtual void prioritize_connections(std::weak_ptr<torrent> t) = 0; │ │ │ │ + │ │ │ │ + virtual void trigger_auto_manage() = 0; │ │ │ │ + │ │ │ │ + virtual void apply_settings_pack(std::shared_ptr<settings_pack> pack) = 0; │ │ │ │ + virtual session_settings const& settings() const = 0; │ │ │ │ + │ │ │ │ + virtual void queue_tracker_request(tracker_request req │ │ │ │ + , std::weak_ptr<request_callback> c) = 0; │ │ │ │ + │ │ │ │ + // peer-classes │ │ │ │ + virtual void set_peer_classes(peer_class_set* s, address const& a, socket_type_t st) = 0; │ │ │ │ + virtual peer_class_pool const& peer_classes() const = 0; │ │ │ │ + virtual peer_class_pool& peer_classes() = 0; │ │ │ │ + virtual bool ignore_unchoke_slots_set(peer_class_set const& set) const = 0; │ │ │ │ + virtual int copy_pertinent_channels(peer_class_set const& set │ │ │ │ + , int channel, bandwidth_channel** dst, int m) = 0; │ │ │ │ + virtual int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) = 0; │ │ │ │ + │ │ │ │ + virtual bandwidth_manager* get_bandwidth_manager(int channel) = 0; │ │ │ │ + │ │ │ │ + virtual void sent_bytes(int bytes_payload, int bytes_protocol) = 0; │ │ │ │ + virtual void received_bytes(int bytes_payload, int bytes_protocol) = 0; │ │ │ │ + virtual void trancieve_ip_packet(int bytes, bool ipv6) = 0; │ │ │ │
    │ │ │ │ ├── html2text {} │ │ │ │ │ @@ -454,68 +454,352 @@ │ │ │ │ │ | | │ │ │ │ │ | auto o = rpc.allocate_observer(std::move(algo), source, node_id()); | │ │ │ │ │ |#if TORRENT_USE_ASSERTS | │ │ │ │ │ | o->m_in_constructor = false; | │ │ │ │ │ |#endif | │ │ │ │ │ | o->flags |= observer::flag_queried; | │ │ │ │ │ |_ _r_p_c_._i_n_v_o_k_e_(_r_e_q_,_ _s_o_u_r_c_e_,_ _o_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_s_e_s_s_i_o_n___h_a_n_d_l_e_._c_p_p_:_6_9_1_ _|_e_x_p_o_s_e_ _t_h_e_ _s_e_q_u_e_n_c_e___n_u_m_b_e_r_,_ _p_u_b_l_i_c___k_e_y_,_ _s_e_c_r_e_t___k_e_y_ _a_n_d_ _s_i_g_n_a_t_u_r_e_ _t_y_p_e_s_ _t_o_ _t_h_e_ _c_l_i_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** eexxppoossee tthhee sseeqquueennccee__nnuummbbeerr,, ppuubblliicc__kkeeyy,, sseeccrreett__kkeeyy aanndd ssiiggnnaattuurree ttyyppeess ttoo tthhee cclliieenntt ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__hhaannddllee..ccpppp::669911 ****** | │ │ │ │ │ -|void session_handle::dht_get_item(sha1_hash const& target) | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_u_t___m_e_t_a_d_a_t_a_._c_p_p_:_2_6_8_ _ _ _ _|_u_s_e_ _t_h_e_ _a_u_x_:_:_w_r_i_t_e___*_ _f_u_n_c_t_i_o_n_s_ _a_n_d_ _t_h_e_ _s_p_a_n_ _h_e_r_e_ _i_n_s_t_e_a_d_,_ _i_t_ _w_i_l_l_ _f_i_t_ _b_e_t_t_e_r_ _w_i_t_h_ _s_e_n_d___b_u_f_f_e_r_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee tthhee aauuxx::::wwrriittee__** ffuunnccttiioonnss aanndd tthhee ssppaann hheerree iinnsstteeaadd,, iitt wwiillll ffiitt bbeetttteerr wwiitthh sseenndd__bbuuffffeerr(()) ********** | │ │ │ │ │ +|****** ....//ssrrcc//uutt__mmeettaaddaattaa..ccpppp::226688 ****** | │ │ │ │ │ +|int metadata_piece_size = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_torrent.valid_metadata()) | │ │ │ │ │ +| e["total_size"] = m_tp.metadata().size(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (type == msg_t::piece) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(piece >= 0 && piece < (m_tp.metadata().size() + 16 * 1024 - 1) / (16 * 1024)); | │ │ │ │ │ +| TORRENT_ASSERT(m_pc.associated_torrent().lock()->valid_metadata()); | │ │ │ │ │ +| TORRENT_ASSERT(m_torrent.valid_metadata()); | │ │ │ │ │ +| | │ │ │ │ │ +| int const offset = piece * 16 * 1024; | │ │ │ │ │ +| metadata = m_tp.metadata().data() + offset; | │ │ │ │ │ +| metadata_piece_size = std::min( | │ │ │ │ │ +| int(m_tp.metadata().size()) - offset, 16 * 1024); | │ │ │ │ │ +| TORRENT_ASSERT(metadata_piece_size > 0); | │ │ │ │ │ +| TORRENT_ASSERT(offset >= 0); | │ │ │ │ │ +| TORRENT_ASSERT(offset + metadata_piece_size <= m_tp.metadata().size()); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|char msg[200]; | │ │ │ │ │ +|char* header = msg; | │ │ │ │ │ +| char* p = &msg[6]; | │ │ │ │ │ +| int const len = bencode(p, e); | │ │ │ │ │ +| int const total_size = 2 + len + metadata_piece_size; | │ │ │ │ │ +| namespace io = aux; | │ │ │ │ │ +| io::write_uint32(total_size, header); | │ │ │ │ │ +| io::write_uint8(bt_peer_connection::msg_extended, header); | │ │ │ │ │ +| io::write_uint8(m_message_index, header); | │ │ │ │ │ +| | │ │ │ │ │ +|_ _ _ _m___p_c_._s_e_n_d___b_u_f_f_e_r_(_{_m_s_g_,_ _l_e_n_ _+_ _6_}_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_1_9_ _ _ _ _ _ _ _ _|_w_e_ _c_o_u_l_d_ _p_r_o_b_a_b_l_y_ _g_e_t_ _a_w_a_y_ _w_i_t_h_ _j_u_s_t_ _s_a_v_i_n_g_ _a_ _f_e_w_ _f_i_e_l_d_s_ _h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** wwee ccoouulldd pprroobbaabbllyy ggeett aawwaayy wwiitthh jjuusstt ssaavviinngg aa ffeeww ffiieellddss hheerree ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::441199 ****** | │ │ │ │ │ +|// --- V2 HASHES --- | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_torrent_file->is_valid() && m_torrent_file->info_hashes().has_v2()) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!p.merkle_trees.empty()) | │ │ │ │ │ +| load_merkle_trees( | │ │ │ │ │ +| std::move(p.merkle_trees) | │ │ │ │ │ +| , std::move(p.merkle_tree_mask) | │ │ │ │ │ +| , std::move(p.verified_leaf_hashes)); | │ │ │ │ │ +| | │ │ │ │ │ +| // we really don't want to store extra copies of the trees | │ │ │ │ │ +| TORRENT_ASSERT(p.merkle_trees.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| if (valid_metadata()) | │ │ │ │ │ +| { | │ │ │ │ │ +| inc_stats_counter(counters::num_total_pieces_added | │ │ │ │ │ +| , m_torrent_file->num_pieces()); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|m_add_torrent_params = std::make_unique(std::move(p)); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| void torrent::load_merkle_trees( | │ │ │ │ │ +| aux::vector, file_index_t> trees_import | │ │ │ │ │ +| , aux::vector, file_index_t> mask | │ │ │ │ │ +| , aux::vector, file_index_t> verified) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| async_call(&session_impl::dht_get_immutable_item, target); | │ │ │ │ │ -|#else | │ │ │ │ │ -| TORRENT_UNUSED(target); | │ │ │ │ │ +| auto const& fs = m_torrent_file->orig_files(); | │ │ │ │ │ +| | │ │ │ │ │ +| std::vector const empty_verified; | │ │ │ │ │ +| for (file_index_t i{0}; i < fs.end_file(); ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (fs.pad_file_at(i) || fs.file_size(i) == 0) | │ │ │ │ │ +| continue; | │ │ │ │ │ +| | │ │ │ │ │ +| if (i >= trees_import.end_index()) break; | │ │ │ │ │ +| std::vector const& verified_bitmask = (i >= verified.end_index()) ? empty_verified : verified[i]; | │ │ │ │ │ +| if (i < mask.end_index() && !mask[i].empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| mask[i].resize(m_merkle_trees[i].size(), false); | │ │ │ │ │ +| m_merkle_trees[i].load_sparse_tree(trees_import[i], mask[i], verified_bitmask); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| m_merkle_trees[i].load_tree(trees_import[i], verified_bitmask); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|_ _v_o_i_d_ _t_o_r_r_e_n_t_:_:_i_n_c___s_t_a_t_s___c_o_u_n_t_e_r_(_i_n_t_ _c_,_ _i_n_t_ _v_a_l_u_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_7_1_5_ _ _ _ _ _ _ _ _|_a_s_s_e_r_t_ _t_h_e_r_e_ _a_r_e_ _n_o_ _o_u_t_s_t_a_n_d_i_n_g_ _a_s_y_n_c_ _o_p_e_r_a_t_i_o_n_s_ _o_n_ _t_h_i_s_ _t_o_r_r_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aasssseerrtt tthheerree aarree nnoo oouuttssttaannddiinngg aassyynncc ooppeerraattiioonnss oonn tthhiiss ttoorrrreenntt ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::771155 ****** | │ │ │ │ │ |#endif | │ │ │ │ │ +| | │ │ │ │ │ +| if (!m_ses.dht()) return false; | │ │ │ │ │ +| if (m_torrent_file->is_valid() && !m_files_checked) return false; | │ │ │ │ │ +| if (!m_announce_to_dht) return false; | │ │ │ │ │ +| if (m_paused) return false; | │ │ │ │ │ +| | │ │ │ │ │ +| // don't announce private torrents | │ │ │ │ │ +| if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false; | │ │ │ │ │ +| if (m_trackers.empty()) return true; | │ │ │ │ │ +| if (!settings().get_bool(settings_pack::use_dht_as_fallback)) return true; | │ │ │ │ │ +| | │ │ │ │ │ +| return std::none_of(m_trackers.begin(), m_trackers.end() | │ │ │ │ │ +| , [](aux::announce_entry const& tr) { return bool(tr.verified); }); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_handle::dht_get_item(std::array key | │ │ │ │ │ -| , std::string salt) | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| torrent::~torrent() | │ │ │ │ │ | { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| async_call(&session_impl::dht_get_mutable_item, key, salt); | │ │ │ │ │ -|#else | │ │ │ │ │ -| TORRENT_UNUSED(key); | │ │ │ │ │ -| TORRENT_UNUSED(salt); | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| for (torrent_list_index_t i{}; i != m_links.end_index(); ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!m_links[i].in_list()) continue; | │ │ │ │ │ +| m_links[i].unlink(m_ses.torrent_list(i), i); | │ │ │ │ │ +| } | │ │ │ │ │ |#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // The invariant can't be maintained here, since the torrent | │ │ │ │ │ +| // is being destructed, all weak references to it have been | │ │ │ │ │ +| // reset, which means that all its peers already have an | │ │ │ │ │ +| // invalidated torrent pointer (so it cannot be verified to be correct) | │ │ │ │ │ +| | │ │ │ │ │ +| // i.e. the invariant can only be maintained if all connections have | │ │ │ │ │ +| // been closed by the time the torrent is destructed. And they are | │ │ │ │ │ +| // supposed to be closed. So we can still do the invariant check. | │ │ │ │ │ +| | │ │ │ │ │ +| // however, the torrent object may be destructed from the main | │ │ │ │ │ +| // thread when shutting down, if the disk cache has references to it. | │ │ │ │ │ +| // this means that the invariant check that this is called from the | │ │ │ │ │ +| // network thread cannot be maintained | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(m_peer_class == peer_class_t{0}); | │ │ │ │ │ +| TORRENT_ASSERT(m_connections.empty()); | │ │ │ │ │ +| // just in case, make sure the session accounting is kept right | │ │ │ │ │ +| for (auto p : m_connections) | │ │ │ │ │ +| m_ses.close_connection(p); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|sha1_hash session_handle::dht_put_item(entry data) | │ │ │ │ │ -|{ | │ │ │ │ │ -| std::vector buf; | │ │ │ │ │ -| bencode(std::back_inserter(buf), data); | │ │ │ │ │ -| sha1_hash const ret = hasher(buf).final(); | │ │ │ │ │ +|_ _v_o_i_d_ _t_o_r_r_e_n_t_:_:_r_e_a_d___p_i_e_c_e_(_p_i_e_c_e___i_n_d_e_x___t_ _c_o_n_s_t_ _p_i_e_c_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_3_3_1_ _ _ _ _ _ _ _|_t_h_e_r_e_'_s_ _s_o_m_e_ _d_u_p_l_i_c_a_t_i_o_n_ _b_e_t_w_e_e_n_ _t_h_i_s_ _f_u_n_c_t_i_o_n_ _a_n_d_ _p_e_e_r___c_o_n_n_e_c_t_i_o_n_:_:_i_n_c_o_m_i_n_g___p_i_e_c_e_(_)_._ _i_s_ _t_h_e_r_e_ _a_ _w_a_y_ _t_o_ _m_e_r_g_e_ _s_o_m_e_t_h_i_n_g_?_ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthheerree''ss ssoommee dduupplliiccaattiioonn bbeettwweeeenn tthhiiss ffuunnccttiioonn aanndd ppeeeerr__ccoonnnneeccttiioonn::::iinnccoommiinngg__ppiieeccee(()).. iiss tthheerree aa wwaayy ttoo mmeerrggee ssoommeetthhiinngg?? ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11333311 ****** | │ │ │ │ │ +|piece_index_t m_piece; | │ │ │ │ │ +| bool m_armed = true; | │ │ │ │ │ +| }; | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| async_call(&session_impl::dht_put_immutable_item, data, ret); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| void torrent::add_piece_async(piece_index_t const piece | │ │ │ │ │ +| , std::vector data, add_piece_flags_t const flags) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| // make sure the piece index is correct | │ │ │ │ │ +| if (piece >= torrent_file().end_piece()) | │ │ │ │ │ +| return; | │ │ │ │ │ +| | │ │ │ │ │ +| // make sure the piece size is correct | │ │ │ │ │ +| if (data.size() != std::size_t(m_torrent_file->piece_size(piece))) | │ │ │ │ │ +| return; | │ │ │ │ │ +| | │ │ │ │ │ +| add_piece(piece, data.data(), flags); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_handle::dht_put_item(std::array key | │ │ │ │ │ -| , std::function& | │ │ │ │ │ -| , std::int64_t&, std::string const&)> cb | │ │ │ │ │ -| , std::string salt) | │ │ │ │ │ +|void torrent::add_piece(piece_index_t const piece, char const* data | │ │ │ │ │ +|, add_piece_flags_t const flags) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| async_call(&session_impl::dht_put_mutable_item, key, cb, salt); | │ │ │ │ │ -|#else | │ │ │ │ │ -| TORRENT_UNUSED(key); | │ │ │ │ │ -| TORRENT_UNUSED(cb); | │ │ │ │ │ -| TORRENT_UNUSED(salt); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| // make sure the piece index is correct | │ │ │ │ │ +| if (piece >= torrent_file().end_piece()) | │ │ │ │ │ +| return; | │ │ │ │ │ +| | │ │ │ │ │ +| int const piece_size = m_torrent_file->piece_size(piece); | │ │ │ │ │ +| int const blocks_in_piece = (piece_size + block_size() - 1) / block_size(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_deleted) return; | │ │ │ │ │ +| | │ │ │ │ │ +| // avoid crash trying to access the picker when there is none | │ │ │ │ │ +| if (m_have_all && !has_picker()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| // we don't support clobbering the piece picker while checking the | │ │ │ │ │ +| // files. We may end up having the same piece multiple times | │ │ │ │ │ +| TORRENT_ASSERT_PRECOND(state() != torrent_status::checking_files | │ │ │ │ │ +| && state() != torrent_status::checking_resume_data); | │ │ │ │ │ +| if (state() == torrent_status::checking_files | │ │ │ │ │ +| || state() == torrent_status::checking_resume_data) | │ │ │ │ │ +| return; | │ │ │ │ │ +| | │ │ │ │ │ +| need_picker(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (picker().have_piece(piece) | │ │ │ │ │ +| && !(flags & torrent_handle::overwrite_existing)) | │ │ │ │ │ +|_ _ _ _r_e_t_u_r_n_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_3_9_6_6_ _ _ _ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _p_u_l_l_e_d_ _o_u_t_ _i_n_t_o_ _a_ _f_r_e_e_ _f_u_n_c_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ccoouulldd pprroobbaabbllyy bbee ppuulllleedd oouutt iinnttoo aa ffrreeee ffuunnccttiioonn ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::33996666 ****** | │ │ │ │ │ +|std::int64_t calc_bytes(file_storage const& fs, piece_count const& pc) | │ │ │ │ │ +| { | │ │ │ │ │ +| // it's an impossible combination to have 0 pieces, but still have one of them be the last piece | │ │ │ │ │ +| TORRENT_ASSERT(!(pc.num_pieces == 0 && pc.last_piece == true)); | │ │ │ │ │ +| | │ │ │ │ │ +| // if we have 0 pieces, we can't have any pad blocks either | │ │ │ │ │ +| TORRENT_ASSERT(!(pc.num_pieces == 0 && pc.pad_bytes > 0)); | │ │ │ │ │ +| | │ │ │ │ │ +| // if we have all pieces, we must also have the last one | │ │ │ │ │ +| TORRENT_ASSERT(!(pc.num_pieces == fs.num_pieces() && pc.last_piece == false)); | │ │ │ │ │ +| | │ │ │ │ │ +| // every block should not be a pad block | │ │ │ │ │ +| TORRENT_ASSERT(pc.pad_bytes <= std::int64_t(pc.num_pieces) * fs.piece_length()); | │ │ │ │ │ +| | │ │ │ │ │ +| return std::int64_t(pc.num_pieces) * fs.piece_length() | │ │ │ │ │ +| - (pc.last_piece ? fs.piece_length() - fs.piece_size(fs.last_piece()) : 0) | │ │ │ │ │ +| - std::int64_t(pc.pad_bytes); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_handle::dht_get_peers(sha1_hash const& info_hash) | │ │ │ │ │ +| // fills in total_wanted, total_wanted_done and total_done | │ │ │ │ │ +|void torrent::bytes_done(torrent_status& st, status_flags_t const flags) const | │ │ │ │ │ +|{ | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| | │ │ │ │ │ +| st.total_done = 0; | │ │ │ │ │ +| st.total_wanted_done = 0; | │ │ │ │ │ +| st.total_wanted = m_size_on_disk; | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(st.total_wanted <= m_torrent_file->total_size()); | │ │ │ │ │ +| TORRENT_ASSERT(st.total_wanted >= 0); | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(!valid_metadata() || m_torrent_file->num_pieces() > 0); | │ │ │ │ │ +| if (!valid_metadata()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_seed_mode || is_seed()) | │ │ │ │ │ +| { | │ │ │ │ │ +| // once we're a seed and remove the piece picker, we stop tracking | │ │ │ │ │ +| // piece- and file priority. We consider everything as being | │ │ │ │ │ +| // "wanted" | │ │ │ │ │ +| st.total_done = m_torrent_file->total_size() - m_padding_bytes; | │ │ │ │ │ +| st.total_wanted_done = m_size_on_disk; | │ │ │ │ │ +| st.total_wanted = m_size_on_disk; | │ │ │ │ │ +| TORRENT_ASSERT(st.total_wanted <= st.total_done); | │ │ │ │ │ +| TORRENT_ASSERT(st.total_wanted_done <= st.total_wanted); | │ │ │ │ │ +| TORRENT_ASSERT(st.total_done <= m_torrent_file->total_size()); | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ +| else if (!has_picker()) | │ │ │ │ │ +| { | │ │ │ │ │ +| st.total_done = 0; | │ │ │ │ │ +|_ _ _ _s_t_._t_o_t_a_l___w_a_n_t_e_d___d_o_n_e_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_9_0_5_ _ _ _ _ _ _ _|_s_h_o_u_l_d_ _t_h_i_s_ _a_l_e_r_t_ _h_a_v_e_ _a_n_ _e_r_r_o_r_ _c_o_d_e_ _i_n_ _i_t_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** sshhoouulldd tthhiiss aalleerrtt hhaavvee aann eerrrroorr ccooddee iinn iitt?? ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44990055 ****** | │ │ │ │ │ +|on_remove_peers(); | │ │ │ │ │ +| TORRENT_ASSERT(m_connections.empty()); | │ │ │ │ │ +| | │ │ │ │ │ +| // post a message to the main thread to destruct | │ │ │ │ │ +| // the torrent object from there | │ │ │ │ │ +| if (m_storage) | │ │ │ │ │ +| { | │ │ │ │ │ +| try { | │ │ │ │ │ +| m_ses.disk_thread().async_stop_torrent(m_storage | │ │ │ │ │ +| , std::bind(&torrent::on_torrent_aborted, shared_from_this())); | │ │ │ │ │ +| } | │ │ │ │ │ +| catch (std::exception const& e) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_UNUSED(e); | │ │ │ │ │ +| m_storage.reset(); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| debug_log("Failed to flush disk cache: %s", e.what()); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| // clients may rely on this alert to be posted, so it's probably a | │ │ │ │ │ +| // good idea to post it here, even though we failed | │ │ │ │ │ +|if (alerts().should_post()) | │ │ │ │ │ +|alerts().emplace_alert(get_handle()); | │ │ │ │ │ +| } | │ │ │ │ │ +| m_ses.deferred_submit_jobs(); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| if (alerts().should_post()) | │ │ │ │ │ +| alerts().emplace_alert(get_handle()); | │ │ │ │ │ +| alerts().emplace_alert(get_handle() | │ │ │ │ │ +| , info_hash(), get_userdata()); | │ │ │ │ │ +|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_9_7_5_ _ _ _ _ _ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _r_e_t_u_r_n_ _o_p_t_i_o_n_a_l_<_>_._ _p_i_e_c_e_ _i_n_d_e_x_ _-_1_ _s_h_o_u_l_d_ _n_o_t_ _b_e_ _a_l_l_o_w_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd rreettuurrnn ooppttiioonnaall<<>>.. ppiieeccee iinnddeexx --11 sshhoouulldd nnoott bbee aalllloowweedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44997755 ****** | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_SUPERSEEDING | │ │ │ │ │ +| void torrent::set_super_seeding(bool const on) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| async_call(&session_impl::dht_get_peers, info_hash); | │ │ │ │ │ -|_#_e_l_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| if (on == m_super_seeding) return; | │ │ │ │ │ +| | │ │ │ │ │ +| m_super_seeding = on; | │ │ │ │ │ +| set_need_save_resume(torrent_handle::if_state_changed); | │ │ │ │ │ +| state_updated(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_super_seeding) return; | │ │ │ │ │ +| | │ │ │ │ │ +| // disable super seeding for all peers | │ │ │ │ │ +| for (auto pc : *this) | │ │ │ │ │ +| { | │ │ │ │ │ +| pc->superseed_piece(piece_index_t(-1), piece_index_t(-1)); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|piece_index_t torrent::get_piece_to_super_seed(typed_bitfield const& bits) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // return a piece with low availability that is not in | │ │ │ │ │ +| // the bitfield and that is not currently being super | │ │ │ │ │ +| // seeded by any peer | │ │ │ │ │ +| TORRENT_ASSERT(m_super_seeding); | │ │ │ │ │ +| | │ │ │ │ │ +| // do a linear search from the first piece | │ │ │ │ │ +| int min_availability = 9999; | │ │ │ │ │ +| std::vector avail_vec; | │ │ │ │ │ +| for (auto const i : m_torrent_file->piece_range()) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (bits[i]) continue; | │ │ │ │ │ +| | │ │ │ │ │ +| int availability = 0; | │ │ │ │ │ +| for (auto pc : *this) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (pc->super_seeded_piece(i)) | │ │ │ │ │ +| { | │ │ │ │ │ +| // avoid super-seeding the same piece to more than one | │ │ │ │ │ +| // peer if we can avoid it. Do this by artificially | │ │ │ │ │ +| // increase the availability | │ │ │ │ │ +| availability = 999; | │ │ │ │ │ +| break; | │ │ │ │ │ +| } | │ │ │ │ │ +| if (pc->has_piece(i)) ++availability; | │ │ │ │ │ +| } | │ │ │ │ │ +| if (availability > min_availability) continue; | │ │ │ │ │ +| if (availability == min_availability) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _ _a_v_a_i_l___v_e_c_._p_u_s_h___b_a_c_k_(_i_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 3|_._._/_s_r_c_/ |this should be an optional, piece index -1 should not be allowed | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_w_e_b___p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_1_9_9_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tthhiiss sshhoouulldd bbee aann ooppttiioonnaall,, ppiieeccee iinnddeexx --11 sshhoouulldd nnoott bbee aalllloowweedd ********** | │ │ │ │ │ |****** ....//ssrrcc//wweebb__ppeeeerr__ccoonnnneeccttiioonn..ccpppp::119999 ****** | │ │ │ │ │ | auto const range = aux::file_piece_range_inclusive(fs, i); | │ │ │ │ │ | for (piece_index_t k = std::get<0>(range); k < std::get<1>(range); ++k) | │ │ │ │ │ | have.clear_bit(k); | │ │ │ │ │ @@ -727,48 +1011,233 @@ │ │ │ │ │ | web->have_files.resize(t->torrent_file().num_files(), false); | │ │ │ │ │ | | │ │ │ │ │ | // the new web seed we're adding only has this file for now | │ │ │ │ │ | // we may add more files later | │ │ │ │ │ | web->redirects[file_index] = redirect_path; | │ │ │ │ │ | if (web->have_files.get_bit(file_index) == false) | │ │ │ │ │ |_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_u_t___m_e_t_a_d_a_t_a_._c_p_p_:_2_6_8_ _ _ _ _|_u_s_e_ _t_h_e_ _a_u_x_:_:_w_r_i_t_e___*_ _f_u_n_c_t_i_o_n_s_ _a_n_d_ _t_h_e_ _s_p_a_n_ _h_e_r_e_ _i_n_s_t_e_a_d_,_ _i_t_ _w_i_l_l_ _f_i_t_ _b_e_t_t_e_r_ _w_i_t_h_ _s_e_n_d___b_u_f_f_e_r_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee tthhee aauuxx::::wwrriittee__** ffuunnccttiioonnss aanndd tthhee ssppaann hheerree iinnsstteeaadd,, iitt wwiillll ffiitt bbeetttteerr wwiitthh sseenndd__bbuuffffeerr(()) ********** | │ │ │ │ │ -|****** ....//ssrrcc//uutt__mmeettaaddaattaa..ccpppp::226688 ****** | │ │ │ │ │ -|int metadata_piece_size = 0; | │ │ │ │ │ +| |_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |instead of having to ask the torrent whether it's in graceful pause mode or not, the peers should keep that state (and the torrent | │ │ │ │ │ +|relevance 3|_3_1_3_3 |should update them when it enters graceful pause). When a peer enters graceful pause mode, it should cancel all outstanding requests| │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_a_n_d_ _c_l_e_a_r_ _i_t_s_ _r_e_q_u_e_s_t_ _q_u_e_u_e_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinnsstteeaadd ooff hhaavviinngg ttoo aasskk tthhee ttoorrrreenntt wwhheetthheerr iitt''ss iinn ggrraacceeffuull ppaauussee mmooddee oorr nnoott,, tthhee ppeeeerrss sshhoouulldd kkeeeepp tthhaatt ssttaattee ((aanndd tthhee ttoorrrreenntt sshhoouulldd uuppddaattee tthheemm wwhheenn iitt eenntteerrss | │ │ │ │ │ +|ggrraacceeffuull ppaauussee)).. WWhheenn aa ppeeeerr eenntteerrss ggrraacceeffuull ppaauussee mmooddee,, iitt sshhoouulldd ccaanncceell aallll oouuttssttaannddiinngg rreeqquueessttss aanndd cclleeaarr iittss rreeqquueesstt qquueeuuee.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::33113333 ****** | │ │ │ │ │ +|// to disk or are in the disk write cache | │ │ │ │ │ +| if (picker.is_piece_finished(p.piece) && !was_finished) | │ │ │ │ │ +| { | │ │ │ │ │ +|#if TORRENT_USE_INVARIANT_CHECKS | │ │ │ │ │ +| check_postcondition post_checker2_(t, false); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| t->verify_piece(p.piece); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (m_torrent.valid_metadata()) | │ │ │ │ │ -| e["total_size"] = m_tp.metadata().size(); | │ │ │ │ │ +| check_graceful_pause(); | │ │ │ │ │ | | │ │ │ │ │ -| if (type == msg_t::piece) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(piece >= 0 && piece < (m_tp.metadata().size() + 16 * 1024 - 1) / (16 * 1024)); | │ │ │ │ │ -| TORRENT_ASSERT(m_pc.associated_torrent().lock()->valid_metadata()); | │ │ │ │ │ -| TORRENT_ASSERT(m_torrent.valid_metadata()); | │ │ │ │ │ +| if (is_disconnecting()) return; | │ │ │ │ │ | | │ │ │ │ │ -| int const offset = piece * 16 * 1024; | │ │ │ │ │ -| metadata = m_tp.metadata().data() + offset; | │ │ │ │ │ -| metadata_piece_size = std::min( | │ │ │ │ │ -| int(m_tp.metadata().size()) - offset, 16 * 1024); | │ │ │ │ │ -| TORRENT_ASSERT(metadata_piece_size > 0); | │ │ │ │ │ -| TORRENT_ASSERT(offset >= 0); | │ │ │ │ │ -| TORRENT_ASSERT(offset + metadata_piece_size <= m_tp.metadata().size()); | │ │ │ │ │ -| } | │ │ │ │ │ +| if (request_a_block(*t, *this)) | │ │ │ │ │ +| m_counters.inc_stats_counter(counters::incoming_piece_picks); | │ │ │ │ │ +| send_block_requests(); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|char msg[200]; | │ │ │ │ │ -|char* header = msg; | │ │ │ │ │ -| char* p = &msg[6]; | │ │ │ │ │ -| int const len = bencode(p, e); | │ │ │ │ │ -| int const total_size = 2 + len + metadata_piece_size; | │ │ │ │ │ -| namespace io = aux; | │ │ │ │ │ -| io::write_uint32(total_size, header); | │ │ │ │ │ -| io::write_uint8(bt_peer_connection::msg_extended, header); | │ │ │ │ │ -| io::write_uint8(m_message_index, header); | │ │ │ │ │ +| void peer_connection::check_graceful_pause() | │ │ │ │ │ +| { | │ │ │ │ │ +|std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ +|if (!t || !t->graceful_pause()) return; | │ │ │ │ │ | | │ │ │ │ │ -|_ _ _ _m___p_c_._s_e_n_d___b_u_f_f_e_r_(_{_m_s_g_,_ _l_e_n_ _+_ _6_}_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| if (m_outstanding_bytes > 0) return; | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| peer_log(peer_log_alert::info, "GRACEFUL_PAUSE", "NO MORE DOWNLOAD"); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| disconnect(errors::torrent_paused, operation_t::bittorrent); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void peer_connection::on_disk_write_complete(storage_error const& error | │ │ │ │ │ +| , peer_request const& p, std::shared_ptr t) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log(peer_log_alert::info)) | │ │ │ │ │ +| { | │ │ │ │ │ +| peer_log(peer_log_alert::info, "FILE_ASYNC_WRITE_COMPLETE", "piece: %d s: %x l: %x e: %s" | │ │ │ │ │ +| , static_cast(p.piece), p.start, p.length, error.ec.message().c_str()); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| m_counters.inc_stats_counter(counters::queued_write_bytes, -p.length); | │ │ │ │ │ +| m_outstanding_writing_bytes -= p.length; | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(m_outstanding_writing_bytes >= 0); | │ │ │ │ │ +| | │ │ │ │ │ +| // every peer is entitled to allocate a disk buffer if it has no writes outstanding | │ │ │ │ │ +| // see the comment in incoming_piece | │ │ │ │ │ +|_ _ _i_f_ _(_m___o_u_t_s_t_a_n_d_i_n_g___w_r_i_t_i_n_g___b_y_t_e_s_ _=_=_ _0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 3|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |once peers are properly put in graceful pause mode, they can cancel all outstanding requests and this test can be removed. | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_4_0_4_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** oonnccee ppeeeerrss aarree pprrooppeerrllyy ppuutt iinn ggrraacceeffuull ppaauussee mmooddee,, tthheeyy ccaann ccaanncceell aallll oouuttssttaannddiinngg rreeqquueessttss aanndd tthhiiss tteesstt ccaann bbee rreemmoovveedd.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::44004444 ****** | │ │ │ │ │ +| if (!p->m_deferred_send_block_requests) | │ │ │ │ │ +| return; | │ │ │ │ │ +| | │ │ │ │ │ +| p->m_deferred_send_block_requests = false; | │ │ │ │ │ +| p->send_block_requests_impl(); | │ │ │ │ │ +| }); | │ │ │ │ │ +| m_deferred_send_block_requests = true; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void peer_connection::send_block_requests_impl() | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| | │ │ │ │ │ +| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ +| if (!t) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_disconnecting) return; | │ │ │ │ │ +| | │ │ │ │ │ +|if (t->graceful_pause()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| // we can't download pieces in these states | │ │ │ │ │ +| if (t->state() == torrent_status::checking_files | │ │ │ │ │ +| || t->state() == torrent_status::checking_resume_data | │ │ │ │ │ +| || t->state() == torrent_status::downloading_metadata) | │ │ │ │ │ +| return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (int(m_download_queue.size()) >= m_desired_queue_size | │ │ │ │ │ +| || t->upload_mode()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| bool const empty_download_queue = m_download_queue.empty(); | │ │ │ │ │ +| | │ │ │ │ │ +| while (!m_request_queue.empty() | │ │ │ │ │ +| && (int(m_download_queue.size()) < m_desired_queue_size | │ │ │ │ │ +| || m_queued_time_critical > 0)) | │ │ │ │ │ +| { | │ │ │ │ │ +| pending_block block = m_request_queue.front(); | │ │ │ │ │ +| | │ │ │ │ │ +| m_request_queue.erase(m_request_queue.begin()); | │ │ │ │ │ +| if (m_queued_time_critical) --m_queued_time_critical; | │ │ │ │ │ +| | │ │ │ │ │ +| // if we're a seed, we don't have a piece picker | │ │ │ │ │ +| // so we don't have to worry about invariants getting | │ │ │ │ │ +| // out of sync with it | │ │ │ │ │ +| if (!t->has_picker()) continue; | │ │ │ │ │ +| | │ │ │ │ │ +| // this can happen if a block times out, is re-requested and | │ │ │ │ │ +| // then arrives "unexpectedly" | │ │ │ │ │ +| if (t->picker().is_downloaded(block.block)) | │ │ │ │ │ +|_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 3|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |new_piece should be an optional. piece index -1 should not be allowed | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_4_7_3_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** nneeww__ppiieeccee sshhoouulldd bbee aann ooppttiioonnaall.. ppiieeccee iinnddeexx --11 sshhoouulldd nnoott bbee aalllloowweedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::44773300 ****** | │ │ │ │ │ +| // pieces may be empty if we don't have metadata yet | │ │ │ │ │ +| if (p.pieces.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| p.progress = 0.f; | │ │ │ │ │ +| p.progress_ppm = 0; | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +|#if TORRENT_NO_FPU | │ │ │ │ │ +| p.progress = 0.f; | │ │ │ │ │ +|#else | │ │ │ │ │ +| p.progress = float(p.pieces.count()) / float(p.pieces.size()); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| p.progress_ppm = int(std::int64_t(p.pieces.count()) * 1000000 / p.pieces.size()); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_SUPERSEEDING | │ │ │ │ │ +|void peer_connection::superseed_piece(piece_index_t const replace_piece | │ │ │ │ │ +|, piece_index_t const new_piece) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| if (is_connecting()) return; | │ │ │ │ │ +| if (in_handshake()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (new_piece == piece_index_t(-1)) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_superseed_piece[0] == piece_index_t(-1)) return; | │ │ │ │ │ +| m_superseed_piece[0] = piece_index_t(-1); | │ │ │ │ │ +| m_superseed_piece[1] = piece_index_t(-1); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| peer_log(peer_log_alert::info, "SUPER_SEEDING", "ending"); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ +| | │ │ │ │ │ +| // this will either send a full bitfield or | │ │ │ │ │ +| // a have-all message, effectively terminating | │ │ │ │ │ +| // super-seeding, since the peer may pick any piece | │ │ │ │ │ +| write_bitfield(); | │ │ │ │ │ +| | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(!has_piece(new_piece)); | │ │ │ │ │ +| | │ │ │ │ │ +|_#_i_f_n_d_e_f_ _T_O_R_R_E_N_T___D_I_S_A_B_L_E___L_O_G_G_I_N_G_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_s_e_s_s_i_o_n___h_a_n_d_l_e_._c_p_p_:_6_9_1_ _|_e_x_p_o_s_e_ _t_h_e_ _s_e_q_u_e_n_c_e___n_u_m_b_e_r_,_ _p_u_b_l_i_c___k_e_y_,_ _s_e_c_r_e_t___k_e_y_ _a_n_d_ _s_i_g_n_a_t_u_r_e_ _t_y_p_e_s_ _t_o_ _t_h_e_ _c_l_i_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** eexxppoossee tthhee sseeqquueennccee__nnuummbbeerr,, ppuubblliicc__kkeeyy,, sseeccrreett__kkeeyy aanndd ssiiggnnaattuurree ttyyppeess ttoo tthhee cclliieenntt ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__hhaannddllee..ccpppp::669911 ****** | │ │ │ │ │ +|void session_handle::dht_get_item(sha1_hash const& target) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| async_call(&session_impl::dht_get_immutable_item, target); | │ │ │ │ │ +|#else | │ │ │ │ │ +| TORRENT_UNUSED(target); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void session_handle::dht_get_item(std::array key | │ │ │ │ │ +| , std::string salt) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| async_call(&session_impl::dht_get_mutable_item, key, salt); | │ │ │ │ │ +|#else | │ │ │ │ │ +| TORRENT_UNUSED(key); | │ │ │ │ │ +| TORRENT_UNUSED(salt); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|sha1_hash session_handle::dht_put_item(entry data) | │ │ │ │ │ +|{ | │ │ │ │ │ +| std::vector buf; | │ │ │ │ │ +| bencode(std::back_inserter(buf), data); | │ │ │ │ │ +| sha1_hash const ret = hasher(buf).final(); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| async_call(&session_impl::dht_put_immutable_item, data, ret); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void session_handle::dht_put_item(std::array key | │ │ │ │ │ +| , std::function& | │ │ │ │ │ +| , std::int64_t&, std::string const&)> cb | │ │ │ │ │ +| , std::string salt) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| async_call(&session_impl::dht_put_mutable_item, key, cb, salt); | │ │ │ │ │ +|#else | │ │ │ │ │ +| TORRENT_UNUSED(key); | │ │ │ │ │ +| TORRENT_UNUSED(cb); | │ │ │ │ │ +| TORRENT_UNUSED(salt); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void session_handle::dht_get_peers(sha1_hash const& info_hash) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| async_call(&session_impl::dht_get_peers, info_hash); | │ │ │ │ │ +|_#_e_l_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_1_1_4_2_ _ _|_c_l_o_s_i_n_g_ _t_h_e_ _u_d_p_ _s_o_c_k_e_t_s_ _h_e_r_e_ _m_e_a_n_s_ _t_h_a_t_ _t_h_e_ _u_T_P_ _c_o_n_n_e_c_t_i_o_n_s_ _c_a_n_n_o_t_ _b_e_ _c_l_o_s_e_d_ _g_r_a_c_e_f_u_l_l_y_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** cclloossiinngg tthhee uuddpp ssoocckkeettss hheerree mmeeaannss tthhaatt tthhee uuTTPP ccoonnnneeccttiioonnss ccaannnnoott bbee cclloosseedd ggrraacceeffuullllyy ********** | │ │ │ │ │ |****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::11114422 ****** | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ | session_log(" aborting all connections (%d)", int(m_connections.size())); | │ │ │ │ │ |#endif | │ │ │ │ │ | // abort all connections | │ │ │ │ │ @@ -1126,483 +1595,14 @@ │ │ │ │ │ | alerts.emplace_alert(pk.bytes, sig.bytes | │ │ │ │ │ | , std::move(salt), seq.value, num); | │ │ │ │ │ | } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ | void put_mutable_callback(dht::item& i | │ │ │ │ │ |_ _ _ _,_ _s_t_d_:_:_f_u_n_c_t_i_o_n_<_v_o_i_d_(_e_n_t_r_y_&_,_ _s_t_d_:_:_a_r_r_a_y_<_c_h_a_r_,_ _6_4_>_&_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -| |_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |instead of having to ask the torrent whether it's in graceful pause mode or not, the peers should keep that state (and the torrent | │ │ │ │ │ -|relevance 3|_3_1_3_3 |should update them when it enters graceful pause). When a peer enters graceful pause mode, it should cancel all outstanding requests| │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_a_n_d_ _c_l_e_a_r_ _i_t_s_ _r_e_q_u_e_s_t_ _q_u_e_u_e_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinnsstteeaadd ooff hhaavviinngg ttoo aasskk tthhee ttoorrrreenntt wwhheetthheerr iitt''ss iinn ggrraacceeffuull ppaauussee mmooddee oorr nnoott,, tthhee ppeeeerrss sshhoouulldd kkeeeepp tthhaatt ssttaattee ((aanndd tthhee ttoorrrreenntt sshhoouulldd uuppddaattee tthheemm wwhheenn iitt eenntteerrss | │ │ │ │ │ -|ggrraacceeffuull ppaauussee)).. WWhheenn aa ppeeeerr eenntteerrss ggrraacceeffuull ppaauussee mmooddee,, iitt sshhoouulldd ccaanncceell aallll oouuttssttaannddiinngg rreeqquueessttss aanndd cclleeaarr iittss rreeqquueesstt qquueeuuee.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::33113333 ****** | │ │ │ │ │ -|// to disk or are in the disk write cache | │ │ │ │ │ -| if (picker.is_piece_finished(p.piece) && !was_finished) | │ │ │ │ │ -| { | │ │ │ │ │ -|#if TORRENT_USE_INVARIANT_CHECKS | │ │ │ │ │ -| check_postcondition post_checker2_(t, false); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| t->verify_piece(p.piece); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| check_graceful_pause(); | │ │ │ │ │ -| | │ │ │ │ │ -| if (is_disconnecting()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (request_a_block(*t, *this)) | │ │ │ │ │ -| m_counters.inc_stats_counter(counters::incoming_piece_picks); | │ │ │ │ │ -| send_block_requests(); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void peer_connection::check_graceful_pause() | │ │ │ │ │ -| { | │ │ │ │ │ -|std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ -|if (!t || !t->graceful_pause()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_outstanding_bytes > 0) return; | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| peer_log(peer_log_alert::info, "GRACEFUL_PAUSE", "NO MORE DOWNLOAD"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| disconnect(errors::torrent_paused, operation_t::bittorrent); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void peer_connection::on_disk_write_complete(storage_error const& error | │ │ │ │ │ -| , peer_request const& p, std::shared_ptr t) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log(peer_log_alert::info)) | │ │ │ │ │ -| { | │ │ │ │ │ -| peer_log(peer_log_alert::info, "FILE_ASYNC_WRITE_COMPLETE", "piece: %d s: %x l: %x e: %s" | │ │ │ │ │ -| , static_cast(p.piece), p.start, p.length, error.ec.message().c_str()); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| m_counters.inc_stats_counter(counters::queued_write_bytes, -p.length); | │ │ │ │ │ -| m_outstanding_writing_bytes -= p.length; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(m_outstanding_writing_bytes >= 0); | │ │ │ │ │ -| | │ │ │ │ │ -| // every peer is entitled to allocate a disk buffer if it has no writes outstanding | │ │ │ │ │ -| // see the comment in incoming_piece | │ │ │ │ │ -|_ _ _i_f_ _(_m___o_u_t_s_t_a_n_d_i_n_g___w_r_i_t_i_n_g___b_y_t_e_s_ _=_=_ _0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 3|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |once peers are properly put in graceful pause mode, they can cancel all outstanding requests and this test can be removed. | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_4_0_4_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** oonnccee ppeeeerrss aarree pprrooppeerrllyy ppuutt iinn ggrraacceeffuull ppaauussee mmooddee,, tthheeyy ccaann ccaanncceell aallll oouuttssttaannddiinngg rreeqquueessttss aanndd tthhiiss tteesstt ccaann bbee rreemmoovveedd.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::44004444 ****** | │ │ │ │ │ -| if (!p->m_deferred_send_block_requests) | │ │ │ │ │ -| return; | │ │ │ │ │ -| | │ │ │ │ │ -| p->m_deferred_send_block_requests = false; | │ │ │ │ │ -| p->send_block_requests_impl(); | │ │ │ │ │ -| }); | │ │ │ │ │ -| m_deferred_send_block_requests = true; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void peer_connection::send_block_requests_impl() | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| | │ │ │ │ │ -| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ -| if (!t) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_disconnecting) return; | │ │ │ │ │ -| | │ │ │ │ │ -|if (t->graceful_pause()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| // we can't download pieces in these states | │ │ │ │ │ -| if (t->state() == torrent_status::checking_files | │ │ │ │ │ -| || t->state() == torrent_status::checking_resume_data | │ │ │ │ │ -| || t->state() == torrent_status::downloading_metadata) | │ │ │ │ │ -| return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (int(m_download_queue.size()) >= m_desired_queue_size | │ │ │ │ │ -| || t->upload_mode()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| bool const empty_download_queue = m_download_queue.empty(); | │ │ │ │ │ -| | │ │ │ │ │ -| while (!m_request_queue.empty() | │ │ │ │ │ -| && (int(m_download_queue.size()) < m_desired_queue_size | │ │ │ │ │ -| || m_queued_time_critical > 0)) | │ │ │ │ │ -| { | │ │ │ │ │ -| pending_block block = m_request_queue.front(); | │ │ │ │ │ -| | │ │ │ │ │ -| m_request_queue.erase(m_request_queue.begin()); | │ │ │ │ │ -| if (m_queued_time_critical) --m_queued_time_critical; | │ │ │ │ │ -| | │ │ │ │ │ -| // if we're a seed, we don't have a piece picker | │ │ │ │ │ -| // so we don't have to worry about invariants getting | │ │ │ │ │ -| // out of sync with it | │ │ │ │ │ -| if (!t->has_picker()) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| // this can happen if a block times out, is re-requested and | │ │ │ │ │ -| // then arrives "unexpectedly" | │ │ │ │ │ -| if (t->picker().is_downloaded(block.block)) | │ │ │ │ │ -|_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 3|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |new_piece should be an optional. piece index -1 should not be allowed | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_4_7_3_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** nneeww__ppiieeccee sshhoouulldd bbee aann ooppttiioonnaall.. ppiieeccee iinnddeexx --11 sshhoouulldd nnoott bbee aalllloowweedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::44773300 ****** | │ │ │ │ │ -| // pieces may be empty if we don't have metadata yet | │ │ │ │ │ -| if (p.pieces.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| p.progress = 0.f; | │ │ │ │ │ -| p.progress_ppm = 0; | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -|#if TORRENT_NO_FPU | │ │ │ │ │ -| p.progress = 0.f; | │ │ │ │ │ -|#else | │ │ │ │ │ -| p.progress = float(p.pieces.count()) / float(p.pieces.size()); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| p.progress_ppm = int(std::int64_t(p.pieces.count()) * 1000000 / p.pieces.size()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_SUPERSEEDING | │ │ │ │ │ -|void peer_connection::superseed_piece(piece_index_t const replace_piece | │ │ │ │ │ -|, piece_index_t const new_piece) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| if (is_connecting()) return; | │ │ │ │ │ -| if (in_handshake()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (new_piece == piece_index_t(-1)) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_superseed_piece[0] == piece_index_t(-1)) return; | │ │ │ │ │ -| m_superseed_piece[0] = piece_index_t(-1); | │ │ │ │ │ -| m_superseed_piece[1] = piece_index_t(-1); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| peer_log(peer_log_alert::info, "SUPER_SEEDING", "ending"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -| | │ │ │ │ │ -| // this will either send a full bitfield or | │ │ │ │ │ -| // a have-all message, effectively terminating | │ │ │ │ │ -| // super-seeding, since the peer may pick any piece | │ │ │ │ │ -| write_bitfield(); | │ │ │ │ │ -| | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(!has_piece(new_piece)); | │ │ │ │ │ -| | │ │ │ │ │ -|_#_i_f_n_d_e_f_ _T_O_R_R_E_N_T___D_I_S_A_B_L_E___L_O_G_G_I_N_G_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_1_9_ _ _ _ _ _ _ _ _|_w_e_ _c_o_u_l_d_ _p_r_o_b_a_b_l_y_ _g_e_t_ _a_w_a_y_ _w_i_t_h_ _j_u_s_t_ _s_a_v_i_n_g_ _a_ _f_e_w_ _f_i_e_l_d_s_ _h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** wwee ccoouulldd pprroobbaabbllyy ggeett aawwaayy wwiitthh jjuusstt ssaavviinngg aa ffeeww ffiieellddss hheerree ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::441199 ****** | │ │ │ │ │ -|// --- V2 HASHES --- | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_torrent_file->is_valid() && m_torrent_file->info_hashes().has_v2()) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (!p.merkle_trees.empty()) | │ │ │ │ │ -| load_merkle_trees( | │ │ │ │ │ -| std::move(p.merkle_trees) | │ │ │ │ │ -| , std::move(p.merkle_tree_mask) | │ │ │ │ │ -| , std::move(p.verified_leaf_hashes)); | │ │ │ │ │ -| | │ │ │ │ │ -| // we really don't want to store extra copies of the trees | │ │ │ │ │ -| TORRENT_ASSERT(p.merkle_trees.empty()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| if (valid_metadata()) | │ │ │ │ │ -| { | │ │ │ │ │ -| inc_stats_counter(counters::num_total_pieces_added | │ │ │ │ │ -| , m_torrent_file->num_pieces()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|m_add_torrent_params = std::make_unique(std::move(p)); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| void torrent::load_merkle_trees( | │ │ │ │ │ -| aux::vector, file_index_t> trees_import | │ │ │ │ │ -| , aux::vector, file_index_t> mask | │ │ │ │ │ -| , aux::vector, file_index_t> verified) | │ │ │ │ │ -| { | │ │ │ │ │ -| auto const& fs = m_torrent_file->orig_files(); | │ │ │ │ │ -| | │ │ │ │ │ -| std::vector const empty_verified; | │ │ │ │ │ -| for (file_index_t i{0}; i < fs.end_file(); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (fs.pad_file_at(i) || fs.file_size(i) == 0) | │ │ │ │ │ -| continue; | │ │ │ │ │ -| | │ │ │ │ │ -| if (i >= trees_import.end_index()) break; | │ │ │ │ │ -| std::vector const& verified_bitmask = (i >= verified.end_index()) ? empty_verified : verified[i]; | │ │ │ │ │ -| if (i < mask.end_index() && !mask[i].empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| mask[i].resize(m_merkle_trees[i].size(), false); | │ │ │ │ │ -| m_merkle_trees[i].load_sparse_tree(trees_import[i], mask[i], verified_bitmask); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| m_merkle_trees[i].load_tree(trees_import[i], verified_bitmask); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|_ _v_o_i_d_ _t_o_r_r_e_n_t_:_:_i_n_c___s_t_a_t_s___c_o_u_n_t_e_r_(_i_n_t_ _c_,_ _i_n_t_ _v_a_l_u_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_7_1_5_ _ _ _ _ _ _ _ _|_a_s_s_e_r_t_ _t_h_e_r_e_ _a_r_e_ _n_o_ _o_u_t_s_t_a_n_d_i_n_g_ _a_s_y_n_c_ _o_p_e_r_a_t_i_o_n_s_ _o_n_ _t_h_i_s_ _t_o_r_r_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aasssseerrtt tthheerree aarree nnoo oouuttssttaannddiinngg aassyynncc ooppeerraattiioonnss oonn tthhiiss ttoorrrreenntt ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::771155 ****** | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (!m_ses.dht()) return false; | │ │ │ │ │ -| if (m_torrent_file->is_valid() && !m_files_checked) return false; | │ │ │ │ │ -| if (!m_announce_to_dht) return false; | │ │ │ │ │ -| if (m_paused) return false; | │ │ │ │ │ -| | │ │ │ │ │ -| // don't announce private torrents | │ │ │ │ │ -| if (m_torrent_file->is_valid() && m_torrent_file->priv()) return false; | │ │ │ │ │ -| if (m_trackers.empty()) return true; | │ │ │ │ │ -| if (!settings().get_bool(settings_pack::use_dht_as_fallback)) return true; | │ │ │ │ │ -| | │ │ │ │ │ -| return std::none_of(m_trackers.begin(), m_trackers.end() | │ │ │ │ │ -| , [](aux::announce_entry const& tr) { return bool(tr.verified); }); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| torrent::~torrent() | │ │ │ │ │ -| { | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -| for (torrent_list_index_t i{}; i != m_links.end_index(); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (!m_links[i].in_list()) continue; | │ │ │ │ │ -| m_links[i].unlink(m_ses.torrent_list(i), i); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| // The invariant can't be maintained here, since the torrent | │ │ │ │ │ -| // is being destructed, all weak references to it have been | │ │ │ │ │ -| // reset, which means that all its peers already have an | │ │ │ │ │ -| // invalidated torrent pointer (so it cannot be verified to be correct) | │ │ │ │ │ -| | │ │ │ │ │ -| // i.e. the invariant can only be maintained if all connections have | │ │ │ │ │ -| // been closed by the time the torrent is destructed. And they are | │ │ │ │ │ -| // supposed to be closed. So we can still do the invariant check. | │ │ │ │ │ -| | │ │ │ │ │ -| // however, the torrent object may be destructed from the main | │ │ │ │ │ -| // thread when shutting down, if the disk cache has references to it. | │ │ │ │ │ -| // this means that the invariant check that this is called from the | │ │ │ │ │ -| // network thread cannot be maintained | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(m_peer_class == peer_class_t{0}); | │ │ │ │ │ -| TORRENT_ASSERT(m_connections.empty()); | │ │ │ │ │ -| // just in case, make sure the session accounting is kept right | │ │ │ │ │ -| for (auto p : m_connections) | │ │ │ │ │ -| m_ses.close_connection(p); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|_ _v_o_i_d_ _t_o_r_r_e_n_t_:_:_r_e_a_d___p_i_e_c_e_(_p_i_e_c_e___i_n_d_e_x___t_ _c_o_n_s_t_ _p_i_e_c_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_3_3_1_ _ _ _ _ _ _ _|_t_h_e_r_e_'_s_ _s_o_m_e_ _d_u_p_l_i_c_a_t_i_o_n_ _b_e_t_w_e_e_n_ _t_h_i_s_ _f_u_n_c_t_i_o_n_ _a_n_d_ _p_e_e_r___c_o_n_n_e_c_t_i_o_n_:_:_i_n_c_o_m_i_n_g___p_i_e_c_e_(_)_._ _i_s_ _t_h_e_r_e_ _a_ _w_a_y_ _t_o_ _m_e_r_g_e_ _s_o_m_e_t_h_i_n_g_?_ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthheerree''ss ssoommee dduupplliiccaattiioonn bbeettwweeeenn tthhiiss ffuunnccttiioonn aanndd ppeeeerr__ccoonnnneeccttiioonn::::iinnccoommiinngg__ppiieeccee(()).. iiss tthheerree aa wwaayy ttoo mmeerrggee ssoommeetthhiinngg?? ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11333311 ****** | │ │ │ │ │ -|piece_index_t m_piece; | │ │ │ │ │ -| bool m_armed = true; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| void torrent::add_piece_async(piece_index_t const piece | │ │ │ │ │ -| , std::vector data, add_piece_flags_t const flags) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| // make sure the piece index is correct | │ │ │ │ │ -| if (piece >= torrent_file().end_piece()) | │ │ │ │ │ -| return; | │ │ │ │ │ -| | │ │ │ │ │ -| // make sure the piece size is correct | │ │ │ │ │ -| if (data.size() != std::size_t(m_torrent_file->piece_size(piece))) | │ │ │ │ │ -| return; | │ │ │ │ │ -| | │ │ │ │ │ -| add_piece(piece, data.data(), flags); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|void torrent::add_piece(piece_index_t const piece, char const* data | │ │ │ │ │ -|, add_piece_flags_t const flags) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| // make sure the piece index is correct | │ │ │ │ │ -| if (piece >= torrent_file().end_piece()) | │ │ │ │ │ -| return; | │ │ │ │ │ -| | │ │ │ │ │ -| int const piece_size = m_torrent_file->piece_size(piece); | │ │ │ │ │ -| int const blocks_in_piece = (piece_size + block_size() - 1) / block_size(); | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_deleted) return; | │ │ │ │ │ -| | │ │ │ │ │ -| // avoid crash trying to access the picker when there is none | │ │ │ │ │ -| if (m_have_all && !has_picker()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| // we don't support clobbering the piece picker while checking the | │ │ │ │ │ -| // files. We may end up having the same piece multiple times | │ │ │ │ │ -| TORRENT_ASSERT_PRECOND(state() != torrent_status::checking_files | │ │ │ │ │ -| && state() != torrent_status::checking_resume_data); | │ │ │ │ │ -| if (state() == torrent_status::checking_files | │ │ │ │ │ -| || state() == torrent_status::checking_resume_data) | │ │ │ │ │ -| return; | │ │ │ │ │ -| | │ │ │ │ │ -| need_picker(); | │ │ │ │ │ -| | │ │ │ │ │ -| if (picker().have_piece(piece) | │ │ │ │ │ -| && !(flags & torrent_handle::overwrite_existing)) | │ │ │ │ │ -|_ _ _ _r_e_t_u_r_n_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_3_9_6_6_ _ _ _ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _p_u_l_l_e_d_ _o_u_t_ _i_n_t_o_ _a_ _f_r_e_e_ _f_u_n_c_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ccoouulldd pprroobbaabbllyy bbee ppuulllleedd oouutt iinnttoo aa ffrreeee ffuunnccttiioonn ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::33996666 ****** | │ │ │ │ │ -|std::int64_t calc_bytes(file_storage const& fs, piece_count const& pc) | │ │ │ │ │ -| { | │ │ │ │ │ -| // it's an impossible combination to have 0 pieces, but still have one of them be the last piece | │ │ │ │ │ -| TORRENT_ASSERT(!(pc.num_pieces == 0 && pc.last_piece == true)); | │ │ │ │ │ -| | │ │ │ │ │ -| // if we have 0 pieces, we can't have any pad blocks either | │ │ │ │ │ -| TORRENT_ASSERT(!(pc.num_pieces == 0 && pc.pad_bytes > 0)); | │ │ │ │ │ -| | │ │ │ │ │ -| // if we have all pieces, we must also have the last one | │ │ │ │ │ -| TORRENT_ASSERT(!(pc.num_pieces == fs.num_pieces() && pc.last_piece == false)); | │ │ │ │ │ -| | │ │ │ │ │ -| // every block should not be a pad block | │ │ │ │ │ -| TORRENT_ASSERT(pc.pad_bytes <= std::int64_t(pc.num_pieces) * fs.piece_length()); | │ │ │ │ │ -| | │ │ │ │ │ -| return std::int64_t(pc.num_pieces) * fs.piece_length() | │ │ │ │ │ -| - (pc.last_piece ? fs.piece_length() - fs.piece_size(fs.last_piece()) : 0) | │ │ │ │ │ -| - std::int64_t(pc.pad_bytes); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // fills in total_wanted, total_wanted_done and total_done | │ │ │ │ │ -|void torrent::bytes_done(torrent_status& st, status_flags_t const flags) const | │ │ │ │ │ -|{ | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| | │ │ │ │ │ -| st.total_done = 0; | │ │ │ │ │ -| st.total_wanted_done = 0; | │ │ │ │ │ -| st.total_wanted = m_size_on_disk; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(st.total_wanted <= m_torrent_file->total_size()); | │ │ │ │ │ -| TORRENT_ASSERT(st.total_wanted >= 0); | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(!valid_metadata() || m_torrent_file->num_pieces() > 0); | │ │ │ │ │ -| if (!valid_metadata()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_seed_mode || is_seed()) | │ │ │ │ │ -| { | │ │ │ │ │ -| // once we're a seed and remove the piece picker, we stop tracking | │ │ │ │ │ -| // piece- and file priority. We consider everything as being | │ │ │ │ │ -| // "wanted" | │ │ │ │ │ -| st.total_done = m_torrent_file->total_size() - m_padding_bytes; | │ │ │ │ │ -| st.total_wanted_done = m_size_on_disk; | │ │ │ │ │ -| st.total_wanted = m_size_on_disk; | │ │ │ │ │ -| TORRENT_ASSERT(st.total_wanted <= st.total_done); | │ │ │ │ │ -| TORRENT_ASSERT(st.total_wanted_done <= st.total_wanted); | │ │ │ │ │ -| TORRENT_ASSERT(st.total_done <= m_torrent_file->total_size()); | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ -| else if (!has_picker()) | │ │ │ │ │ -| { | │ │ │ │ │ -| st.total_done = 0; | │ │ │ │ │ -|_ _ _ _s_t_._t_o_t_a_l___w_a_n_t_e_d___d_o_n_e_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_9_0_5_ _ _ _ _ _ _ _|_s_h_o_u_l_d_ _t_h_i_s_ _a_l_e_r_t_ _h_a_v_e_ _a_n_ _e_r_r_o_r_ _c_o_d_e_ _i_n_ _i_t_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** sshhoouulldd tthhiiss aalleerrtt hhaavvee aann eerrrroorr ccooddee iinn iitt?? ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44990055 ****** | │ │ │ │ │ -|on_remove_peers(); | │ │ │ │ │ -| TORRENT_ASSERT(m_connections.empty()); | │ │ │ │ │ -| | │ │ │ │ │ -| // post a message to the main thread to destruct | │ │ │ │ │ -| // the torrent object from there | │ │ │ │ │ -| if (m_storage) | │ │ │ │ │ -| { | │ │ │ │ │ -| try { | │ │ │ │ │ -| m_ses.disk_thread().async_stop_torrent(m_storage | │ │ │ │ │ -| , std::bind(&torrent::on_torrent_aborted, shared_from_this())); | │ │ │ │ │ -| } | │ │ │ │ │ -| catch (std::exception const& e) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_UNUSED(e); | │ │ │ │ │ -| m_storage.reset(); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| debug_log("Failed to flush disk cache: %s", e.what()); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| // clients may rely on this alert to be posted, so it's probably a | │ │ │ │ │ -| // good idea to post it here, even though we failed | │ │ │ │ │ -|if (alerts().should_post()) | │ │ │ │ │ -|alerts().emplace_alert(get_handle()); | │ │ │ │ │ -| } | │ │ │ │ │ -| m_ses.deferred_submit_jobs(); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| if (alerts().should_post()) | │ │ │ │ │ -| alerts().emplace_alert(get_handle()); | │ │ │ │ │ -| alerts().emplace_alert(get_handle() | │ │ │ │ │ -| , info_hash(), get_userdata()); | │ │ │ │ │ -|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _3_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_9_7_5_ _ _ _ _ _ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _r_e_t_u_r_n_ _o_p_t_i_o_n_a_l_<_>_._ _p_i_e_c_e_ _i_n_d_e_x_ _-_1_ _s_h_o_u_l_d_ _n_o_t_ _b_e_ _a_l_l_o_w_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd rreettuurrnn ooppttiioonnaall<<>>.. ppiieeccee iinnddeexx --11 sshhoouulldd nnoott bbee aalllloowweedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44997755 ****** | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_SUPERSEEDING | │ │ │ │ │ -| void torrent::set_super_seeding(bool const on) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (on == m_super_seeding) return; | │ │ │ │ │ -| | │ │ │ │ │ -| m_super_seeding = on; | │ │ │ │ │ -| set_need_save_resume(torrent_handle::if_state_changed); | │ │ │ │ │ -| state_updated(); | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_super_seeding) return; | │ │ │ │ │ -| | │ │ │ │ │ -| // disable super seeding for all peers | │ │ │ │ │ -| for (auto pc : *this) | │ │ │ │ │ -| { | │ │ │ │ │ -| pc->superseed_piece(piece_index_t(-1), piece_index_t(-1)); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|piece_index_t torrent::get_piece_to_super_seed(typed_bitfield const& bits) | │ │ │ │ │ -|{ | │ │ │ │ │ -| // return a piece with low availability that is not in | │ │ │ │ │ -| // the bitfield and that is not currently being super | │ │ │ │ │ -| // seeded by any peer | │ │ │ │ │ -| TORRENT_ASSERT(m_super_seeding); | │ │ │ │ │ -| | │ │ │ │ │ -| // do a linear search from the first piece | │ │ │ │ │ -| int min_availability = 9999; | │ │ │ │ │ -| std::vector avail_vec; | │ │ │ │ │ -| for (auto const i : m_torrent_file->piece_range()) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (bits[i]) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| int availability = 0; | │ │ │ │ │ -| for (auto pc : *this) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (pc->super_seeded_piece(i)) | │ │ │ │ │ -| { | │ │ │ │ │ -| // avoid super-seeding the same piece to more than one | │ │ │ │ │ -| // peer if we can avoid it. Do this by artificially | │ │ │ │ │ -| // increase the availability | │ │ │ │ │ -| availability = 999; | │ │ │ │ │ -| break; | │ │ │ │ │ -| } | │ │ │ │ │ -| if (pc->has_piece(i)) ++availability; | │ │ │ │ │ -| } | │ │ │ │ │ -| if (availability > min_availability) continue; | │ │ │ │ │ -| if (availability == min_availability) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _ _a_v_a_i_l___v_e_c_._p_u_s_h___b_a_c_k_(_i_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 3|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |move this into it's own .cpp file | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_r_p_c___m_a_n_a_g_e_r_._c_p_p_:_7_1_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmoovvee tthhiiss iinnttoo iitt''ss oowwnn ..ccpppp ffiillee ********** | │ │ │ │ │ |****** ....//ssrrcc//kkaaddeemmlliiaa//rrppcc__mmaannaaggeerr..ccpppp::7711 ****** | │ │ │ │ │ |#include | │ │ │ │ │ |#include | │ │ │ │ │ |#include | │ │ │ │ │ @@ -1650,123 +1650,14 @@ │ │ │ │ │ | } | │ │ │ │ │ | else | │ │ │ │ │ | { | │ │ │ │ │ | flags &= ~flag_ipv6_address; | │ │ │ │ │ | m_addr.v4 = ep.address().to_v4().to_bytes(); | │ │ │ │ │ | } | │ │ │ │ │ |_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |unify url_seed and http_seed with just web_seed, using the web_seed_entry. | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_t_o_r_r_e_n_t___h_a_n_d_l_e_._h_p_p_:_5_3_5_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uunniiffyy uurrll__sseeeedd aanndd hhttttpp__sseeeedd wwiitthh jjuusstt wweebb__sseeeedd,, uussiinngg tthhee wweebb__sseeeedd__eennttrryy.. ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ttoorrrreenntt__hhaannddllee..hhpppp::553355 ****** | │ │ │ │ │ -|// one returned from ``trackers()`` and will replace it. If you want an | │ │ │ │ │ -| // immediate effect, you have to call force_reannounce(). See | │ │ │ │ │ -| // announce_entry. | │ │ │ │ │ -| // | │ │ │ │ │ -| // ``post_trackers()`` is the asynchronous version of ``trackers()``. It | │ │ │ │ │ -| // will trigger a tracker_list_alert to be posted. | │ │ │ │ │ -| // | │ │ │ │ │ -| // ``add_tracker()`` will look if the specified tracker is already in the | │ │ │ │ │ -| // set. If it is, it doesn't do anything. If it's not in the current set | │ │ │ │ │ -| // of trackers, it will insert it in the tier specified in the | │ │ │ │ │ -| // announce_entry. | │ │ │ │ │ -| // | │ │ │ │ │ -| // The updated set of trackers will be saved in the resume data, and when | │ │ │ │ │ -| // a torrent is started with resume data, the trackers from the resume | │ │ │ │ │ -| // data will replace the original ones. | │ │ │ │ │ -| std::vector trackers() const; | │ │ │ │ │ -| void replace_trackers(std::vector const&) const; | │ │ │ │ │ -| void add_tracker(announce_entry const&) const; | │ │ │ │ │ -| void post_trackers() const; | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|// ``add_url_seed()`` adds another url to the torrent's list of url | │ │ │ │ │ -| // seeds. If the given url already exists in that list, the call has no | │ │ │ │ │ -| // effect. The torrent will connect to the server and try to download | │ │ │ │ │ -| // pieces from it, unless it's paused, queued, checking or seeding. | │ │ │ │ │ -| // ``remove_url_seed()`` removes the given url if it exists already. | │ │ │ │ │ -| // ``url_seeds()`` return a set of the url seeds currently in this | │ │ │ │ │ -| // torrent. Note that URLs that fails may be removed automatically from | │ │ │ │ │ -| // the list. | │ │ │ │ │ -| // | │ │ │ │ │ -| // See http-seeding_ for more information. | │ │ │ │ │ -| void add_url_seed(std::string const& url) const; | │ │ │ │ │ -| void remove_url_seed(std::string const& url) const; | │ │ │ │ │ -| std::set url_seeds() const; | │ │ │ │ │ -| | │ │ │ │ │ -| // These functions are identical as the ``*_url_seed()`` variants, but | │ │ │ │ │ -| // they operate on `BEP 17`_ web seeds instead of `BEP 19`_. | │ │ │ │ │ -| // | │ │ │ │ │ -| // See http-seeding_ for more information. | │ │ │ │ │ -| void add_http_seed(std::string const& url) const; | │ │ │ │ │ -| void remove_http_seed(std::string const& url) const; | │ │ │ │ │ -| std::set http_seeds() const; | │ │ │ │ │ -| | │ │ │ │ │ -| // add the specified extension to this torrent. The ``ext`` argument is | │ │ │ │ │ -| // a function that will be called from within libtorrent's context | │ │ │ │ │ -| // passing in the internal torrent object and the specified userdata | │ │ │ │ │ -| // pointer. The function is expected to return a shared pointer to | │ │ │ │ │ -| // a torrent_plugin instance. | │ │ │ │ │ -| void add_extension( | │ │ │ │ │ -| std::function(torrent_handle const&, client_data_t)> const& ext | │ │ │ │ │ -|_ _ _ _,_ _c_l_i_e_n_t___d_a_t_a___t_ _u_s_e_r_d_a_t_a_ _=_ _c_l_i_e_n_t___d_a_t_a___t_{_}_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |dh_key_exchange should probably move into its own file | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_e___c_r_y_p_t_o_._h_p_p_:_7_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ddhh__kkeeyy__eexxcchhaannggee sshhoouulldd pprroobbaabbllyy mmoovvee iinnttoo iittss oowwnn ffiillee ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppee__ccrryyppttoo..hhpppp::7722 ****** | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -| | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ -| | │ │ │ │ │ -| namespace mp = boost::multiprecision; | │ │ │ │ │ -| | │ │ │ │ │ -| using key_t = mp::number>; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_EXTRA_EXPORT std::array export_key(key_t const& k); | │ │ │ │ │ -| | │ │ │ │ │ -| // RC4 state from libtomcrypt | │ │ │ │ │ -| struct rc4 { | │ │ │ │ │ -| int x; | │ │ │ │ │ -| int y; | │ │ │ │ │ -| aux::array buf; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -|class TORRENT_EXTRA_EXPORT dh_key_exchange | │ │ │ │ │ -|{ | │ │ │ │ │ -| public: | │ │ │ │ │ -| dh_key_exchange(); | │ │ │ │ │ -| | │ │ │ │ │ -| // Get local public key | │ │ │ │ │ -| key_t const& get_local_key() const { return m_dh_local_key; } | │ │ │ │ │ -| | │ │ │ │ │ -| // read remote_pubkey, generate and store shared secret in | │ │ │ │ │ -| // m_dh_shared_secret. | │ │ │ │ │ -| void compute_secret(std::uint8_t const* remote_pubkey); | │ │ │ │ │ -| void compute_secret(key_t const& remote_pubkey); | │ │ │ │ │ -| | │ │ │ │ │ -| key_t const& get_secret() const { return m_dh_shared_secret; } | │ │ │ │ │ -| | │ │ │ │ │ -| sha1_hash const& get_hash_xor_mask() const { return m_xor_mask; } | │ │ │ │ │ -| | │ │ │ │ │ -| private: | │ │ │ │ │ -| | │ │ │ │ │ -| key_t m_dh_local_key; | │ │ │ │ │ -| key_t m_dh_local_secret; | │ │ │ │ │ -| key_t m_dh_shared_secret; | │ │ │ │ │ -| sha1_hash m_xor_mask; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| struct TORRENT_EXTRA_EXPORT encryption_handler | │ │ │ │ │ -| { | │ │ │ │ │ -| std::tuple>> | │ │ │ │ │ -| encrypt(span> iovec); | │ │ │ │ │ -| | │ │ │ │ │ -|_ _ _i_n_t_ _d_e_c_r_y_p_t_(_a_u_x_:_:_c_r_y_p_t_o___r_e_c_e_i_v_e___b_u_f_f_e_r_&_ _r_e_c_v___b_u_f_f_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |factor out predictive pieces and all operations on it into a separate class (to use as member here instead) | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_t_o_r_r_e_n_t_._h_p_p_:_1_4_2_3_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ffaaccttoorr oouutt pprreeddiiccttiivvee ppiieecceess aanndd aallll ooppeerraattiioonnss oonn iitt iinnttoo aa sseeppaarraattee ccllaassss ((ttoo uussee aass mmeemmbbeerr hheerree iinnsstteeaadd)) ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ttoorrrreenntt..hhpppp::11442233 ****** | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ | std::string m_trackerid; | │ │ │ │ │ @@ -1868,67 +1759,124 @@ │ │ │ │ │ | | │ │ │ │ │ | // the number of pieces we completed the check of | │ │ │ │ │ | piece_index_t m_num_checked_pieces{0}; | │ │ │ │ │ | | │ │ │ │ │ | // if the error occurred on a file, this is the index of that file | │ │ │ │ │ | // there are a few special cases, when this is negative. See | │ │ │ │ │ |_ _ _/_/_ _s_e_t___e_r_r_o_r_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |everything but payload counters and rates could probably be removed from here | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_t_a_t_._h_p_p_:_2_5_7_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** eevveerryytthhiinngg bbuutt ppaayyllooaadd ccoouunntteerrss aanndd rraatteess ccoouulldd pprroobbaabbllyy bbee rreemmoovveedd ffrroomm hheerree ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssttaatt..hhpppp::225577 ****** | │ │ │ │ │ -|// peer_connection is opened and have some previous | │ │ │ │ │ -| // transfers from earlier connections. | │ │ │ │ │ -| void add_stat(std::int64_t downloaded, std::int64_t uploaded) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_stat[download_payload].offset(downloaded); | │ │ │ │ │ -| m_stat[upload_payload].offset(uploaded); | │ │ │ │ │ -| } | │ │ │ │ │ +|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |use string_view for device_name | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_e_n_u_m___n_e_t_._h_p_p_:_1_6_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee ssttrriinngg__vviieeww ffoorr ddeevviiccee__nnaammee ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//eennuumm__nneett..hhpppp::116644 ****** | │ │ │ │ │ +|// return nullopt. | │ │ │ │ │ +| TORRENT_EXTRA_EXPORT boost::optional
    get_gateway( | │ │ │ │ │ +| ip_interface const& iface, span routes); | │ │ │ │ │ | | │ │ │ │ │ -| int last_payload_downloaded() const | │ │ │ │ │ -| { return m_stat[download_payload].counter(); } | │ │ │ │ │ -| int last_payload_uploaded() const | │ │ │ │ │ -| { return m_stat[upload_payload].counter(); } | │ │ │ │ │ -| int last_protocol_downloaded() const | │ │ │ │ │ -| { return m_stat[download_protocol].counter(); } | │ │ │ │ │ -| int last_protocol_uploaded() const | │ │ │ │ │ -| { return m_stat[upload_protocol].counter(); } | │ │ │ │ │ +| // returns whether there is a route to the specified device for for any global | │ │ │ │ │ +| // internet address of the specified address family. | │ │ │ │ │ +| TORRENT_EXTRA_EXPORT bool has_internet_route(string_view device, int family | │ │ │ │ │ +| , span routes); | │ │ │ │ │ | | │ │ │ │ │ -| // these are the channels we keep stats for | │ │ │ │ │ -| enum | │ │ │ │ │ -| { | │ │ │ │ │ -|upload_payload, | │ │ │ │ │ -|upload_protocol, | │ │ │ │ │ -| download_payload, | │ │ │ │ │ -| download_protocol, | │ │ │ │ │ -| upload_ip_protocol, | │ │ │ │ │ -| download_ip_protocol, | │ │ │ │ │ -| num_channels | │ │ │ │ │ -| }; | │ │ │ │ │ +| // returns whether there are *any* routes to the internet in the routing | │ │ │ │ │ +| // table. This can be used to determine if the routing table is fully | │ │ │ │ │ +| // populated or not. | │ │ │ │ │ +| TORRENT_EXTRA_EXPORT bool has_any_internet_route(span routes); | │ │ │ │ │ | | │ │ │ │ │ -| void clear() | │ │ │ │ │ +| // attempt to bind socket to the device with the specified name. For systems | │ │ │ │ │ +| // that don't support SO_BINDTODEVICE the socket will be bound to one of the | │ │ │ │ │ +| // IP addresses of the specified device. In this case it is necessary to | │ │ │ │ │ +| // verify the local endpoint of the socket once the connection is established. | │ │ │ │ │ +| // the returned address is the ip the socket was bound to (or address_v4::any() | │ │ │ │ │ +| // in case SO_BINDTODEVICE succeeded and we don't need to verify it). | │ │ │ │ │ +|template | │ │ │ │ │ +|address bind_socket_to_device(io_context& ios, Socket& sock | │ │ │ │ │ +| , tcp const& protocol | │ │ │ │ │ +| , char const* device_name, int port, error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| tcp::endpoint bind_ep(address_v4::any(), std::uint16_t(port)); | │ │ │ │ │ +| | │ │ │ │ │ +| address ip = make_address(device_name, ec); | │ │ │ │ │ +| if (!ec) | │ │ │ │ │ | { | │ │ │ │ │ -| for (int i = 0; i < num_channels; ++i) | │ │ │ │ │ -| m_stat[i].clear(); | │ │ │ │ │ +| // this is to cover the case where "0.0.0.0" is considered any IPv4 or | │ │ │ │ │ +| // IPv6 address. If we're asking to be bound to an IPv6 address and | │ │ │ │ │ +| // providing 0.0.0.0 as the device, turn it into "::" | │ │ │ │ │ +| if (ip == address_v4::any() && protocol == boost::asio::ip::tcp::v6()) | │ │ │ │ │ +| ip = address_v6::any(); | │ │ │ │ │ +| bind_ep.address(ip); | │ │ │ │ │ +| // it appears to be an IP. Just bind to that address | │ │ │ │ │ +| sock.bind(bind_ep, ec); | │ │ │ │ │ +| return bind_ep.address(); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| stat_channel const& operator[](int i) const | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_HAS_BINDTODEVICE | │ │ │ │ │ +| // try to use SO_BINDTODEVICE here, if that exists. If it fails, | │ │ │ │ │ +| // fall back to the mechanism we have below | │ │ │ │ │ +| aux::bind_device(sock, device_name, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +|#endif | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(i >= 0 && i < num_channels); | │ │ │ │ │ -| return m_stat[i]; | │ │ │ │ │ -| } | │ │ │ │ │ +|_ _ _ _e_c_._c_l_e_a_r_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |unify url_seed and http_seed with just web_seed, using the web_seed_entry. | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_t_o_r_r_e_n_t___h_a_n_d_l_e_._h_p_p_:_5_3_5_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uunniiffyy uurrll__sseeeedd aanndd hhttttpp__sseeeedd wwiitthh jjuusstt wweebb__sseeeedd,, uussiinngg tthhee wweebb__sseeeedd__eennttrryy.. ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ttoorrrreenntt__hhaannddllee..hhpppp::553355 ****** | │ │ │ │ │ +|// one returned from ``trackers()`` and will replace it. If you want an | │ │ │ │ │ +| // immediate effect, you have to call force_reannounce(). See | │ │ │ │ │ +| // announce_entry. | │ │ │ │ │ +| // | │ │ │ │ │ +| // ``post_trackers()`` is the asynchronous version of ``trackers()``. It | │ │ │ │ │ +| // will trigger a tracker_list_alert to be posted. | │ │ │ │ │ +| // | │ │ │ │ │ +| // ``add_tracker()`` will look if the specified tracker is already in the | │ │ │ │ │ +| // set. If it is, it doesn't do anything. If it's not in the current set | │ │ │ │ │ +| // of trackers, it will insert it in the tier specified in the | │ │ │ │ │ +| // announce_entry. | │ │ │ │ │ +| // | │ │ │ │ │ +| // The updated set of trackers will be saved in the resume data, and when | │ │ │ │ │ +| // a torrent is started with resume data, the trackers from the resume | │ │ │ │ │ +| // data will replace the original ones. | │ │ │ │ │ +| std::vector trackers() const; | │ │ │ │ │ +| void replace_trackers(std::vector const&) const; | │ │ │ │ │ +| void add_tracker(announce_entry const&) const; | │ │ │ │ │ +| void post_trackers() const; | │ │ │ │ │ | | │ │ │ │ │ -| private: | │ │ │ │ │ | | │ │ │ │ │ -| stat_channel m_stat[num_channels]; | │ │ │ │ │ -| }; | │ │ │ │ │ +|// ``add_url_seed()`` adds another url to the torrent's list of url | │ │ │ │ │ +| // seeds. If the given url already exists in that list, the call has no | │ │ │ │ │ +| // effect. The torrent will connect to the server and try to download | │ │ │ │ │ +| // pieces from it, unless it's paused, queued, checking or seeding. | │ │ │ │ │ +| // ``remove_url_seed()`` removes the given url if it exists already. | │ │ │ │ │ +| // ``url_seeds()`` return a set of the url seeds currently in this | │ │ │ │ │ +| // torrent. Note that URLs that fails may be removed automatically from | │ │ │ │ │ +| // the list. | │ │ │ │ │ +| // | │ │ │ │ │ +| // See http-seeding_ for more information. | │ │ │ │ │ +| void add_url_seed(std::string const& url) const; | │ │ │ │ │ +| void remove_url_seed(std::string const& url) const; | │ │ │ │ │ +| std::set url_seeds() const; | │ │ │ │ │ | | │ │ │ │ │ -|} | │ │ │ │ │ +| // These functions are identical as the ``*_url_seed()`` variants, but | │ │ │ │ │ +| // they operate on `BEP 17`_ web seeds instead of `BEP 19`_. | │ │ │ │ │ +| // | │ │ │ │ │ +| // See http-seeding_ for more information. | │ │ │ │ │ +| void add_http_seed(std::string const& url) const; | │ │ │ │ │ +| void remove_http_seed(std::string const& url) const; | │ │ │ │ │ +| std::set http_seeds() const; | │ │ │ │ │ | | │ │ │ │ │ -|_#_e_n_d_i_f_ _/_/_ _T_O_R_R_E_N_T___S_T_A_T___H_P_P___I_N_C_L_U_D_E_D_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| // add the specified extension to this torrent. The ``ext`` argument is | │ │ │ │ │ +| // a function that will be called from within libtorrent's context | │ │ │ │ │ +| // passing in the internal torrent object and the specified userdata | │ │ │ │ │ +| // pointer. The function is expected to return a shared pointer to | │ │ │ │ │ +| // a torrent_plugin instance. | │ │ │ │ │ +| void add_extension( | │ │ │ │ │ +| std::function(torrent_handle const&, client_data_t)> const& ext | │ │ │ │ │ +|_ _ _ _,_ _c_l_i_e_n_t___d_a_t_a___t_ _u_s_e_r_d_a_t_a_ _=_ _c_l_i_e_n_t___d_a_t_a___t_{_}_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |if we make this be a disk_buffer_holder instead we would save a copy use allocate_disk_receive_buffer and | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_w_e_b___p_e_e_r___c_o_n_n_e_c_t_i_o_n_._h_p_p_:_1_1_9_ _ _ _|_r_e_l_e_a_s_e___d_i_s_k___r_e_c_e_i_v_e___b_u_f_f_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** iiff wwee mmaakkee tthhiiss bbee aa ddiisskk__bbuuffffeerr__hhoollddeerr iinnsstteeaadd wwee wwoouulldd ssaavvee aa ccooppyy uussee aallllooccaattee__ddiisskk__rreecceeiivvee__bbuuffffeerr aanndd rreelleeaassee__ddiisskk__rreecceeiivvee__bbuuffffeerr ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//wweebb__ppeeeerr__ccoonnnneeccttiioonn..hhpppp::111199 ****** | │ │ │ │ │ |piece_block_progress downloading_piece_progress() const override; | │ │ │ │ │ | | │ │ │ │ │ | void handle_padfile(); | │ │ │ │ │ @@ -1971,69 +1919,121 @@ │ │ │ │ │ | // the number of responses we've received so far on | │ │ │ │ │ | // this connection | │ │ │ │ │ | int m_num_responses; | │ │ │ │ │ | }; | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ |_#_e_n_d_i_f_ _/_/_ _T_O_R_R_E_N_T___W_E_B___P_E_E_R___C_O_N_N_E_C_T_I_O_N___H_P_P___I_N_C_L_U_D_E_D_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |use string_view for device_name | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_e_n_u_m___n_e_t_._h_p_p_:_1_6_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee ssttrriinngg__vviieeww ffoorr ddeevviiccee__nnaammee ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//eennuumm__nneett..hhpppp::116644 ****** | │ │ │ │ │ -|// return nullopt. | │ │ │ │ │ -| TORRENT_EXTRA_EXPORT boost::optional
    get_gateway( | │ │ │ │ │ -| ip_interface const& iface, span routes); | │ │ │ │ │ +|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |dh_key_exchange should probably move into its own file | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_e___c_r_y_p_t_o_._h_p_p_:_7_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ddhh__kkeeyy__eexxcchhaannggee sshhoouulldd pprroobbaabbllyy mmoovvee iinnttoo iittss oowwnn ffiillee ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppee__ccrryyppttoo..hhpppp::7722 ****** | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ | | │ │ │ │ │ -| // returns whether there is a route to the specified device for for any global | │ │ │ │ │ -| // internet address of the specified address family. | │ │ │ │ │ -| TORRENT_EXTRA_EXPORT bool has_internet_route(string_view device, int family | │ │ │ │ │ -| , span routes); | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ | | │ │ │ │ │ -| // returns whether there are *any* routes to the internet in the routing | │ │ │ │ │ -| // table. This can be used to determine if the routing table is fully | │ │ │ │ │ -| // populated or not. | │ │ │ │ │ -| TORRENT_EXTRA_EXPORT bool has_any_internet_route(span routes); | │ │ │ │ │ +| namespace mp = boost::multiprecision; | │ │ │ │ │ | | │ │ │ │ │ -| // attempt to bind socket to the device with the specified name. For systems | │ │ │ │ │ -| // that don't support SO_BINDTODEVICE the socket will be bound to one of the | │ │ │ │ │ -| // IP addresses of the specified device. In this case it is necessary to | │ │ │ │ │ -| // verify the local endpoint of the socket once the connection is established. | │ │ │ │ │ -| // the returned address is the ip the socket was bound to (or address_v4::any() | │ │ │ │ │ -| // in case SO_BINDTODEVICE succeeded and we don't need to verify it). | │ │ │ │ │ -|template | │ │ │ │ │ -|address bind_socket_to_device(io_context& ios, Socket& sock | │ │ │ │ │ -| , tcp const& protocol | │ │ │ │ │ -| , char const* device_name, int port, error_code& ec) | │ │ │ │ │ +| using key_t = mp::number>; | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_EXTRA_EXPORT std::array export_key(key_t const& k); | │ │ │ │ │ +| | │ │ │ │ │ +| // RC4 state from libtomcrypt | │ │ │ │ │ +| struct rc4 { | │ │ │ │ │ +| int x; | │ │ │ │ │ +| int y; | │ │ │ │ │ +| aux::array buf; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +|class TORRENT_EXTRA_EXPORT dh_key_exchange | │ │ │ │ │ +|{ | │ │ │ │ │ +| public: | │ │ │ │ │ +| dh_key_exchange(); | │ │ │ │ │ +| | │ │ │ │ │ +| // Get local public key | │ │ │ │ │ +| key_t const& get_local_key() const { return m_dh_local_key; } | │ │ │ │ │ +| | │ │ │ │ │ +| // read remote_pubkey, generate and store shared secret in | │ │ │ │ │ +| // m_dh_shared_secret. | │ │ │ │ │ +| void compute_secret(std::uint8_t const* remote_pubkey); | │ │ │ │ │ +| void compute_secret(key_t const& remote_pubkey); | │ │ │ │ │ +| | │ │ │ │ │ +| key_t const& get_secret() const { return m_dh_shared_secret; } | │ │ │ │ │ +| | │ │ │ │ │ +| sha1_hash const& get_hash_xor_mask() const { return m_xor_mask; } | │ │ │ │ │ +| | │ │ │ │ │ +| private: | │ │ │ │ │ +| | │ │ │ │ │ +| key_t m_dh_local_key; | │ │ │ │ │ +| key_t m_dh_local_secret; | │ │ │ │ │ +| key_t m_dh_shared_secret; | │ │ │ │ │ +| sha1_hash m_xor_mask; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| struct TORRENT_EXTRA_EXPORT encryption_handler | │ │ │ │ │ | { | │ │ │ │ │ -| tcp::endpoint bind_ep(address_v4::any(), std::uint16_t(port)); | │ │ │ │ │ +| std::tuple>> | │ │ │ │ │ +| encrypt(span> iovec); | │ │ │ │ │ | | │ │ │ │ │ -| address ip = make_address(device_name, ec); | │ │ │ │ │ -| if (!ec) | │ │ │ │ │ +|_ _ _i_n_t_ _d_e_c_r_y_p_t_(_a_u_x_:_:_c_r_y_p_t_o___r_e_c_e_i_v_e___b_u_f_f_e_r_&_ _r_e_c_v___b_u_f_f_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |everything but payload counters and rates could probably be removed from here | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_t_a_t_._h_p_p_:_2_5_7_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** eevveerryytthhiinngg bbuutt ppaayyllooaadd ccoouunntteerrss aanndd rraatteess ccoouulldd pprroobbaabbllyy bbee rreemmoovveedd ffrroomm hheerree ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssttaatt..hhpppp::225577 ****** | │ │ │ │ │ +|// peer_connection is opened and have some previous | │ │ │ │ │ +| // transfers from earlier connections. | │ │ │ │ │ +| void add_stat(std::int64_t downloaded, std::int64_t uploaded) | │ │ │ │ │ | { | │ │ │ │ │ -| // this is to cover the case where "0.0.0.0" is considered any IPv4 or | │ │ │ │ │ -| // IPv6 address. If we're asking to be bound to an IPv6 address and | │ │ │ │ │ -| // providing 0.0.0.0 as the device, turn it into "::" | │ │ │ │ │ -| if (ip == address_v4::any() && protocol == boost::asio::ip::tcp::v6()) | │ │ │ │ │ -| ip = address_v6::any(); | │ │ │ │ │ -| bind_ep.address(ip); | │ │ │ │ │ -| // it appears to be an IP. Just bind to that address | │ │ │ │ │ -| sock.bind(bind_ep, ec); | │ │ │ │ │ -| return bind_ep.address(); | │ │ │ │ │ +| m_stat[download_payload].offset(downloaded); | │ │ │ │ │ +| m_stat[upload_payload].offset(uploaded); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ +| int last_payload_downloaded() const | │ │ │ │ │ +| { return m_stat[download_payload].counter(); } | │ │ │ │ │ +| int last_payload_uploaded() const | │ │ │ │ │ +| { return m_stat[upload_payload].counter(); } | │ │ │ │ │ +| int last_protocol_downloaded() const | │ │ │ │ │ +| { return m_stat[download_protocol].counter(); } | │ │ │ │ │ +| int last_protocol_uploaded() const | │ │ │ │ │ +| { return m_stat[upload_protocol].counter(); } | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_HAS_BINDTODEVICE | │ │ │ │ │ -| // try to use SO_BINDTODEVICE here, if that exists. If it fails, | │ │ │ │ │ -| // fall back to the mechanism we have below | │ │ │ │ │ -| aux::bind_device(sock, device_name, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // these are the channels we keep stats for | │ │ │ │ │ +| enum | │ │ │ │ │ | { | │ │ │ │ │ -|_ _ _ _e_c_._c_l_e_a_r_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|upload_payload, | │ │ │ │ │ +|upload_protocol, | │ │ │ │ │ +| download_payload, | │ │ │ │ │ +| download_protocol, | │ │ │ │ │ +| upload_ip_protocol, | │ │ │ │ │ +| download_ip_protocol, | │ │ │ │ │ +| num_channels | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| void clear() | │ │ │ │ │ +| { | │ │ │ │ │ +| for (int i = 0; i < num_channels; ++i) | │ │ │ │ │ +| m_stat[i].clear(); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| stat_channel const& operator[](int i) const | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(i >= 0 && i < num_channels); | │ │ │ │ │ +| return m_stat[i]; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| private: | │ │ │ │ │ +| | │ │ │ │ │ +| stat_channel m_stat[num_channels]; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|_#_e_n_d_i_f_ _/_/_ _T_O_R_R_E_N_T___S_T_A_T___H_P_P___I_N_C_L_U_D_E_D_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 3|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |to improve memory locality and scanning performance, turn the routing table into a single vector with boundaries for the nodes | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_k_a_d_e_m_l_i_a_/_r_o_u_t_i_n_g___t_a_b_l_e_._h_p_p_:_1_5_3_|_i_n_s_t_e_a_d_._ _P_e_r_h_a_p_s_ _r_e_p_l_a_c_e_m_e_n_t_ _n_o_d_e_s_ _s_h_o_u_l_d_ _b_e_ _i_n_ _a_ _s_e_p_a_r_a_t_e_ _v_e_c_t_o_r_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ttoo iimmpprroovvee mmeemmoorryy llooccaalliittyy aanndd ssccaannnniinngg ppeerrffoorrmmaannccee,, ttuurrnn tthhee rroouuttiinngg ttaabbllee iinnttoo aa ssiinnggllee vveeccttoorr wwiitthh bboouunnddaarriieess ffoorr tthhee nnooddeess iinnsstteeaadd.. PPeerrhhaappss rreeppllaacceemmeenntt nnooddeess sshhoouulldd | │ │ │ │ │ |bbee iinn aa sseeppaarraattee vveeccttoorr.. ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..hhpppp::115533 ****** | │ │ │ │ │ |// * Nodes are not marked as being stale, they keep a counter | │ │ │ │ │ |// that tells how many times in a row they have failed. When | │ │ │ │ │ @@ -2136,14 +2136,18 @@ │ │ │ │ │ | , move_flags_t flags, storage_error& ec); | │ │ │ │ │ | | │ │ │ │ │ | // deletes the files on fs from save_path according to options. Options may | │ │ │ │ │ | // opt to only delete the partfile | │ │ │ │ │ | TORRENT_EXTRA_EXPORT void | │ │ │ │ │ | delete_files(file_storage const& fs, std::string const& save_path | │ │ │ │ │ |_ _ _,_ _s_t_d_:_:_s_t_r_i_n_g_ _c_o_n_s_t_&_ _p_a_r_t___f_i_l_e___n_a_m_e_,_ _r_e_m_o_v_e___f_l_a_g_s___t_ _o_p_t_i_o_n_s_,_ _s_t_o_r_a_g_e___e_r_r_o_r_&_ _e_c_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_t_e_s_t_/_t_e_s_t___p_i_e_c_e___p_i_c_k_e_r_._c_p_p_:|test picking with partial pieces and other peers present so that both backup_pieces and backup_pieces2 are used | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_2_8_7_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ppiicckkiinngg wwiitthh ppaarrttiiaall ppiieecceess aanndd ootthheerr ppeeeerrss pprreesseenntt ssoo tthhaatt bbootthh bbaacckkuupp__ppiieecceess aanndd bbaacckkuupp__ppiieecceess22 aarree uusseedd ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____pp_ii_ee_cc_ee____pp_ii_cc_kk_ee_rr_.._cc_pp_pp_::_22_88_77_00_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _2_|_._._/_t_e_s_t_/_t_e_s_t___s_t_o_r_a_g_e_._c_p_p_:_7_6_9_ _ _|_s_p_l_i_t_ _t_h_i_s_ _t_e_s_t_ _u_p_ _i_n_t_o_ _s_m_a_l_l_e_r_ _p_a_r_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** sspplliitt tthhiiss tteesstt uupp iinnttoo ssmmaalllleerr ppaarrttss ********** | │ │ │ │ │ |****** ....//tteesstt//tteesstt__ssttoorraaggee..ccpppp::776699 ****** | │ │ │ │ │ |io->submit_jobs(); | │ │ │ │ │ | ios.restart(); | │ │ │ │ │ | run_until(ios, done); | │ │ │ │ │ | | │ │ │ │ │ @@ -2298,597 +2302,179 @@ │ │ │ │ │ | bool ret = verify_message(ent, msg_desc, msg_keys, error_string); | │ │ │ │ │ | TEST_CHECK(ret); | │ │ │ │ │ | TEST_CHECK(msg_keys[0]); | │ │ │ │ │ | if (msg_keys[0]) TEST_EQUAL(msg_keys[0].string_value(), "test"); | │ │ │ │ │ | TEST_CHECK(msg_keys[1]); | │ │ │ │ │ | TEST_CHECK(msg_keys[2]); | │ │ │ │ │ |_ _i_f_ _(_m_s_g___k_e_y_s_[_2_]_)_ _T_E_S_T___E_Q_U_A_L_(_m_s_g___k_e_y_s_[_2_]_._s_t_r_i_n_g___v_a_l_u_e_(_)_,_ _"_t_e_s_t_2_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_t_e_s_t_/_t_e_s_t___p_i_e_c_e___p_i_c_k_e_r_._c_p_p_:|test picking with partial pieces and other peers present so that both backup_pieces and backup_pieces2 are used | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_2_8_7_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ppiicckkiinngg wwiitthh ppaarrttiiaall ppiieecceess aanndd ootthheerr ppeeeerrss pprreesseenntt ssoo tthhaatt bbootthh bbaacckkuupp__ppiieecceess aanndd bbaacckkuupp__ppiieecceess22 aarree uusseedd ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____pp_ii_ee_cc_ee____pp_ii_cc_kk_ee_rr_.._cc_pp_pp_::_22_88_77_00_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_u_p_n_p_._c_p_p_:_1_0_6_ _ _ _ _ _ _ _ _ _ _ _|_u_s_e_ _b_o_o_s_t_:_:_a_s_i_o_:_:_i_p_:_:_n_e_t_w_o_r_k_ _i_n_s_t_e_a_d_ _o_f_ _n_e_t_m_a_s_k_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee bboooosstt::::aassiioo::::iipp::::nneettwwoorrkk iinnsstteeaadd ooff nneettmmaasskk ********** | │ │ │ │ │ -|****** ....//ssrrcc//uuppnnpp..ccpppp::110066 ****** | │ │ │ │ │ -|static error_code ignore_error; | │ │ │ │ │ -| | │ │ │ │ │ -|upnp::rootdevice::rootdevice() = default; | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -|upnp::rootdevice::~rootdevice() | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(magic == 1337); | │ │ │ │ │ -| magic = 0; | │ │ │ │ │ -|} | │ │ │ │ │ -|#else | │ │ │ │ │ -|upnp::rootdevice::~rootdevice() = default; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -|upnp::rootdevice::rootdevice(rootdevice const&) = default; | │ │ │ │ │ -|upnp::rootdevice& upnp::rootdevice::operator=(rootdevice const&) & = default; | │ │ │ │ │ -|upnp::rootdevice::rootdevice(rootdevice&&) noexcept = default; | │ │ │ │ │ -|upnp::rootdevice& upnp::rootdevice::operator=(rootdevice&&) & = default; | │ │ │ │ │ -| | │ │ │ │ │ -|upnp::upnp(io_context& ios | │ │ │ │ │ -|, aux::session_settings const& settings | │ │ │ │ │ -| , aux::portmap_callback& cb | │ │ │ │ │ -| , address_v4 const listen_address | │ │ │ │ │ -| , address_v4 const netmask | │ │ │ │ │ -| , std::string listen_device | │ │ │ │ │ -| , listen_socket_handle ls) | │ │ │ │ │ -| : m_settings(settings) | │ │ │ │ │ -| , m_callback(cb) | │ │ │ │ │ -| , m_io_service(ios) | │ │ │ │ │ -| , m_resolver(ios) | │ │ │ │ │ -| , m_multicast(ios) | │ │ │ │ │ -| , m_unicast(ios) | │ │ │ │ │ -| , m_broadcast_timer(ios) | │ │ │ │ │ -| , m_refresh_timer(ios) | │ │ │ │ │ -| , m_map_timer(ios) | │ │ │ │ │ -| , m_listen_address(listen_address) | │ │ │ │ │ -| , m_netmask(netmask) | │ │ │ │ │ -| , m_device(std::move(listen_device)) | │ │ │ │ │ -|#if TORRENT_USE_SSL | │ │ │ │ │ -| , m_ssl_ctx(ssl::context::sslv23_client) | │ │ │ │ │ -|#endif | │ │ │ │ │ -| , m_listen_handle(std::move(ls)) | │ │ │ │ │ -|{ | │ │ │ │ │ -|#if TORRENT_USE_SSL | │ │ │ │ │ -| m_ssl_ctx.set_verify_mode(ssl::context::verify_none); | │ │ │ │ │ -|#endif | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void upnp::start() | │ │ │ │ │ -|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_b_d_e_c_o_d_e_._c_p_p_:_8_2_6_ _ _ _ _ _ _ _ _|_a_t_t_e_m_p_t_ _t_o_ _s_i_m_p_l_i_f_y_ _t_h_i_s_ _i_m_p_l_e_m_e_n_t_a_t_i_o_n_ _b_y_ _e_m_b_r_a_c_i_n_g_ _t_h_e_ _s_p_a_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aatttteemmpptt ttoo ssiimmpplliiffyy tthhiiss iimmpplleemmeennttaattiioonn bbyy eemmbbrraacciinngg tthhee ssppaann ********** | │ │ │ │ │ -|****** ....//ssrrcc//bbddeeccooddee..ccpppp::882266 ****** | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| bdecode_node bdecode(span buffer | │ │ │ │ │ -| , error_code& ec, int* error_pos, int depth_limit, int token_limit) | │ │ │ │ │ -| { | │ │ │ │ │ -| bdecode_node ret; | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -| | │ │ │ │ │ -| if (buffer.size() > bdecode_token::max_offset) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (error_pos) *error_pos = 0; | │ │ │ │ │ -| ec = bdecode_errors::limit_exceeded; | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // this is the stack of bdecode_token indices, into m_tokens. | │ │ │ │ │ -| // sp is the stack pointer, as index into the array, stack | │ │ │ │ │ -| int sp = 0; | │ │ │ │ │ -| TORRENT_ALLOCA(stack, stack_frame, depth_limit); | │ │ │ │ │ -| | │ │ │ │ │ -|char const* start = buffer.data(); | │ │ │ │ │ -|char const* end = start + buffer.size(); | │ │ │ │ │ -| char const* const orig_start = start; | │ │ │ │ │ -| | │ │ │ │ │ -| if (start == end) | │ │ │ │ │ -| TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); | │ │ │ │ │ -| | │ │ │ │ │ -| while (start <= end) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (start >= end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); | │ │ │ │ │ -| | │ │ │ │ │ -| if (sp >= depth_limit) | │ │ │ │ │ -| TORRENT_FAIL_BDECODE(bdecode_errors::depth_exceeded); | │ │ │ │ │ -| | │ │ │ │ │ -| --token_limit; | │ │ │ │ │ -| if (token_limit < 0) | │ │ │ │ │ -| TORRENT_FAIL_BDECODE(bdecode_errors::limit_exceeded); | │ │ │ │ │ -| | │ │ │ │ │ -| // look for a new token | │ │ │ │ │ -| char const t = *start; | │ │ │ │ │ -| | │ │ │ │ │ -| int const current_frame = sp; | │ │ │ │ │ -| | │ │ │ │ │ -| // if we're currently parsing a dictionary, assert that | │ │ │ │ │ -| // every other node is a string. | │ │ │ │ │ -| if (current_frame > 0 | │ │ │ │ │ -| && ret.m_tokens[stack[current_frame - 1].token].type == bdecode_token::dict) | │ │ │ │ │ +| | |technically, this is where the transaction of moving the files is completed. This is where the new save_path should be committed. If| │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_2_9_4 |there is an error in the code below, that should not prevent the new save path to be set. Maybe it would make sense to make the | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_s_a_v_e___p_a_t_h_ _a_n_ _i_n_-_o_u_t_ _p_a_r_a_m_e_t_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteecchhnniiccaallllyy,, tthhiiss iiss wwhheerree tthhee ttrraannssaaccttiioonn ooff mmoovviinngg tthhee ffiilleess iiss ccoommpplleetteedd.. TThhiiss iiss wwhheerree tthhee nneeww ssaavvee__ppaatthh sshhoouulldd bbee ccoommmmiitttteedd.. IIff tthheerree iiss aann eerrrroorr iinn tthhee ccooddee bbeellooww,,| │ │ │ │ │ +|tthhaatt sshhoouulldd nnoott pprreevveenntt tthhee nneeww ssaavvee ppaatthh ttoo bbee sseett.. MMaayybbee iitt wwoouulldd mmaakkee sseennssee ttoo mmaakkee tthhee ssaavvee__ppaatthh aann iinn--oouutt ppaarraammeetteerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::229944 ****** | │ │ │ │ │ +|while (--file_index >= file_index_t(0)) | │ │ │ │ │ | { | │ │ │ │ │ -| if (stack[current_frame - 1].state == 0) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _ _ _/_/_ _t_h_e_ _c_u_r_r_e_n_t_ _p_a_r_e_n_t_ _i_s_ _a_ _d_i_c_t_ _a_n_d_ _w_e_ _a_r_e_ _p_a_r_s_i_n_g_ _a_ _k_e_y_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/ |just make this peer not have the pieces associated with the file we just requested. Only when it doesn't have any of the file do the| │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_w_e_b___p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_6_2_6_ _ _ _|_f_o_l_l_o_w_i_n_g_ _p_a_d_ _f_i_l_e_s_ _w_i_l_l_ _m_a_k_e_ _i_t_ _c_o_m_p_l_i_c_a_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** jjuusstt mmaakkee tthhiiss ppeeeerr nnoott hhaavvee tthhee ppiieecceess aassssoocciiaatteedd wwiitthh tthhee ffiillee wwee jjuusstt rreeqquueesstteedd.. OOnnllyy wwhheenn iitt ddooeessnn''tt hhaavvee aannyy ooff tthhee ffiillee ddoo tthhee ffoolllloowwiinngg ppaadd ffiilleess wwiillll mmaakkee iitt | │ │ │ │ │ -|ccoommpplliiccaatteedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//wweebb__ppeeeerr__ccoonnnneeccttiioonn..ccpppp::662266 ****** | │ │ │ │ │ -| peer_connection::received_invalid_data(index, single_peer); | │ │ │ │ │ -| | │ │ │ │ │ -| // if we don't think we have any of the files, allow banning the web seed | │ │ │ │ │ -| if (num_have_pieces() == 0) return true; | │ │ │ │ │ -| | │ │ │ │ │ -| // don't disconnect, we won't request anything from this file again | │ │ │ │ │ -| return false; | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void web_peer_connection::on_receive_padfile() | │ │ │ │ │ -|{ | │ │ │ │ │ -| handle_padfile(); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void web_peer_connection::handle_error(int const bytes_left) | │ │ │ │ │ -|{ | │ │ │ │ │ -| std::shared_ptr t = associated_torrent().lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|// temporarily unavailable, retry later | │ │ │ │ │ -| t->retry_web_seed(this, m_parser.header_duration("retry-after")); | │ │ │ │ │ -| if (t->alerts().should_post()) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::string const error_msg = to_string(m_parser.status_code()).data() | │ │ │ │ │ -| + (" " + m_parser.message()); | │ │ │ │ │ -| t->alerts().emplace_alert(t->get_handle(), m_url | │ │ │ │ │ -| , error_msg); | │ │ │ │ │ -| } | │ │ │ │ │ -| received_bytes(0, bytes_left); | │ │ │ │ │ -| disconnect(error_code(m_parser.status_code(), http_category()), operation_t::bittorrent, failure); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void web_peer_connection::disable(error_code const& ec) | │ │ │ │ │ -|{ | │ │ │ │ │ -| // we should not try this server again. | │ │ │ │ │ -| m_web->disabled = true; | │ │ │ │ │ -| disconnect(ec, operation_t::bittorrent, peer_error); | │ │ │ │ │ -| if (m_web->ephemeral) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::shared_ptr t = associated_torrent().lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -| t->remove_web_seed_conn(this); | │ │ │ │ │ -| } | │ │ │ │ │ -| m_web = nullptr; | │ │ │ │ │ -| TORRENT_ASSERT(is_disconnecting()); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void web_peer_connection::handle_redirect(int const bytes_left) | │ │ │ │ │ -|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_9_9_ _ _ _|_i_s_ _t_h_e_r_e_ _a_ _r_e_a_s_o_n_ _n_o_t_ _t_o_ _m_o_v_e_ _a_l_l_ _o_f_ _t_h_i_s_ _i_n_t_o_ _i_n_i_t_(_)_?_ _a_n_d_ _j_u_s_t_ _p_o_s_t_ _i_t_ _t_o_ _t_h_e_ _i_o___c_o_n_t_e_x_t_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iiss tthheerree aa rreeaassoonn nnoott ttoo mmoovvee aallll ooff tthhiiss iinnttoo iinniitt(())?? aanndd jjuusstt ppoosstt iitt ttoo tthhee iioo__ccoonntteexxtt?? ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::559999 ****** | │ │ │ │ │ -|try | │ │ │ │ │ -|#endif | │ │ │ │ │ -| { | │ │ │ │ │ -| (this->*f)(std::forward(a)...); | │ │ │ │ │ -| } | │ │ │ │ │ -|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ -| catch (system_error const& e) { | │ │ │ │ │ -| alerts().emplace_alert(e.code(), e.what()); | │ │ │ │ │ -| pause(); | │ │ │ │ │ -| } catch (std::exception const& e) { | │ │ │ │ │ -| alerts().emplace_alert(error_code(), e.what()); | │ │ │ │ │ -| pause(); | │ │ │ │ │ -| } catch (...) { | │ │ │ │ │ -| alerts().emplace_alert(error_code(), "unknown error"); | │ │ │ │ │ -| pause(); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| // This function is called by the creating thread, not in the message loop's | │ │ │ │ │ -| // io_context thread. | │ │ │ │ │ -|void session_impl::start_session() | │ │ │ │ │ -|{ | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| session_log("start session"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_SSL | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| m_ssl_ctx.set_default_verify_paths(ec); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (ec) session_log("SSL set_default verify_paths failed: %s", ec.message().c_str()); | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -|#endif | │ │ │ │ │ -|_#_i_f_ _d_e_f_i_n_e_d_ _T_O_R_R_E_N_T___W_I_N_D_O_W_S_ _&_&_ _d_e_f_i_n_e_d_ _T_O_R_R_E_N_T___U_S_E___O_P_E_N_S_S_L_ _&_&_ _!_d_e_f_i_n_e_d_ _T_O_R_R_E_N_T___W_I_N_R_T_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_7_6_1_ _ _ _|_t_h_e_ _i_p_ _f_i_l_t_e_r_ _s_h_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _s_a_v_e_d_ _h_e_r_e_ _t_o_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhee iipp ffiilltteerr sshhoouulldd pprroobbaabbllyy bbee ssaavveedd hheerree ttoooo ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::776611 ****** | │ │ │ │ │ -|m_lsd_announce_timer.async_wait([this](error_code const& e) { | │ │ │ │ │ -| wrap(&session_impl::on_lsd_announce, e); } ); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| session_log(" done starting session"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| // this applies unchoke settings from m_settings | │ │ │ │ │ -| recalculate_unchoke_slots(); | │ │ │ │ │ -| | │ │ │ │ │ -| // apply all m_settings to this session | │ │ │ │ │ -| run_all_updates(*this); | │ │ │ │ │ -| reopen_listen_sockets(false); | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_INVARIANT_CHECKS | │ │ │ │ │ -| check_invariant(); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION <= 2 | │ │ │ │ │ -|void session_impl::save_state(entry* eptr, save_state_flags_t const flags) const | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| entry& e = *eptr; | │ │ │ │ │ -| // make it a dict | │ │ │ │ │ -| e.dict(); | │ │ │ │ │ -| | │ │ │ │ │ -| if (flags & session::save_settings) | │ │ │ │ │ -| { | │ │ │ │ │ -| entry::dictionary_type& sett = e["settings"].dict(); | │ │ │ │ │ -| save_settings_to_dict(non_default_settings(m_settings), sett); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| if (flags & session::save_dht_settings) | │ │ │ │ │ -| { | │ │ │ │ │ -| e["dht"] = dht::save_dht_settings(get_dht_settings()); | │ │ │ │ │ -| } | │ │ │ │ │ +| // files moved out to absolute paths are not moved | │ │ │ │ │ +| if (f.file_absolute_path(file_index)) continue; | │ │ │ │ │ | | │ │ │ │ │ -| if (m_dht && (flags & session::save_dht_state)) | │ │ │ │ │ -| { | │ │ │ │ │ -| e["dht state"] = dht::save_dht_state(m_dht->state()); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // if we ended up copying the file, don't do anything during | │ │ │ │ │ +| // roll-back | │ │ │ │ │ +| if (copied_files[file_index]) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ -| for (auto const& ext : m_ses_extensions[plugins_all_idx]) | │ │ │ │ │ -| { | │ │ │ │ │ -| ext->save_state(*eptr); | │ │ │ │ │ -|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_3_8_8_2 |make a list for torrents that want to be announced on the DHT so we don't have to loop over all torrents, just to find the ones that| │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_w_a_n_t_ _t_o_ _a_n_n_o_u_n_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmaakkee aa lliisstt ffoorr ttoorrrreennttss tthhaatt wwaanntt ttoo bbee aannnnoouunncceedd oonn tthhee DDHHTT ssoo wwee ddoonn''tt hhaavvee ttoo lloooopp oovveerr aallll ttoorrrreennttss,, jjuusstt ttoo ffiinndd tthhee oonneess tthhaatt wwaanntt ttoo aannnnoouunnccee ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::33888822 ****** | │ │ │ │ │ -|if (!m_dht_torrents.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::shared_ptr t; | │ │ │ │ │ -| do | │ │ │ │ │ -| { | │ │ │ │ │ -| t = m_dht_torrents.front().lock(); | │ │ │ │ │ -| m_dht_torrents.pop_front(); | │ │ │ │ │ -| } while (!t && !m_dht_torrents.empty()); | │ │ │ │ │ +| std::string const old_path = combine_path(save_path, f.file_path(file_index)); | │ │ │ │ │ +| std::string const new_path = combine_path(new_save_path, f.file_path(file_index)); | │ │ │ │ │ | | │ │ │ │ │ -| if (t) | │ │ │ │ │ -| { | │ │ │ │ │ -| t->dht_announce(); | │ │ │ │ │ -| return; | │ │ │ │ │ +| // ignore errors when rolling back | │ │ │ │ │ +| storage_error ignore; | │ │ │ │ │ +| move_file(new_path, old_path, ignore); | │ │ │ │ │ | } | │ │ │ │ │ -| } | │ │ │ │ │ -| if (m_torrents.empty()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_next_dht_torrent >= m_torrents.size()) | │ │ │ │ │ -| m_next_dht_torrent = 0; | │ │ │ │ │ -| m_torrents[m_next_dht_torrent]->dht_announce(); | │ │ │ │ │ -|++m_next_dht_torrent; | │ │ │ │ │ -|if (m_next_dht_torrent >= m_torrents.size()) | │ │ │ │ │ -| m_next_dht_torrent = 0; | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| void session_impl::on_lsd_announce(error_code const& e) | │ │ │ │ │ -| { | │ │ │ │ │ -| COMPLETE_ASYNC("session_impl::on_lsd_announce"); | │ │ │ │ │ -| m_stats_counters.inc_stats_counter(counters::on_lsd_counter); | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| if (e) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_abort) return; | │ │ │ │ │ -| | │ │ │ │ │ -| ADD_OUTSTANDING_ASYNC("session_impl::on_lsd_announce"); | │ │ │ │ │ -| // announce on local network every 5 minutes | │ │ │ │ │ -| int const delay = std::max(m_settings.get_int(settings_pack::local_service_announce_interval) | │ │ │ │ │ -| / std::max(int(m_torrents.size()), 1), 1); | │ │ │ │ │ -| m_lsd_announce_timer.expires_after(seconds(delay)); | │ │ │ │ │ -| m_lsd_announce_timer.async_wait([this](error_code const& err) { | │ │ │ │ │ -| wrap(&session_impl::on_lsd_announce, err); }); | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_torrents.empty()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_next_lsd_torrent >= m_torrents.size()) | │ │ │ │ │ -| m_next_lsd_torrent = 0; | │ │ │ │ │ -| m_torrents[m_next_lsd_torrent]->lsd_announce(); | │ │ │ │ │ -| ++m_next_lsd_torrent; | │ │ │ │ │ -| if (m_next_lsd_torrent >= m_torrents.size()) | │ │ │ │ │ -|_ _ _ _m___n_e_x_t___l_s_d___t_o_r_r_e_n_t_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_5_1_5_ _ _|_t_h_i_s_ _f_u_n_c_t_i_o_n_ _s_h_o_u_l_d_ _b_e_ _r_e_m_o_v_e_d_ _a_n_d_ _u_s_e_r_s_ _n_e_e_d_ _t_o_ _d_e_a_l_ _w_i_t_h_ _t_h_e_ _m_o_r_e_ _g_e_n_e_r_i_c_ _c_a_s_e_ _o_f_ _h_a_v_i_n_g_ _m_u_l_t_i_p_l_e_ _l_i_s_t_e_n_ _p_o_r_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ffuunnccttiioonn sshhoouulldd bbee rreemmoovveedd aanndd uusseerrss nneeeedd ttoo ddeeaall wwiitthh tthhee mmoorree ggeenneerriicc ccaassee ooff hhaavviinngg mmuullttiippllee lliisstteenn ppoorrttss ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55551155 ****** | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (!node_list.empty() && nodes.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| session_log("ERROR: failed to parse DHT bootstrap list: %s", node_list.c_str()); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| for (auto const& n : nodes) | │ │ │ │ │ -| add_dht_router(n); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::update_count_slow() | │ │ │ │ │ -| { | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| for (auto const& tp : m_torrents) | │ │ │ │ │ -| { | │ │ │ │ │ -| tp->on_inactivity_tick(ec); | │ │ │ │ │ +| return { status_t::fatal_disk_error, save_path }; | │ │ │ │ │ | } | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -|std::uint16_t session_impl::listen_port() const | │ │ │ │ │ -|{ | │ │ │ │ │ -| return listen_port(nullptr); | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| std::uint16_t session_impl::listen_port(listen_socket_t* sock) const | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_listen_sockets.empty()) return 0; | │ │ │ │ │ -| if (sock) | │ │ │ │ │ +|std::set subdirs; | │ │ │ │ │ +| for (auto const i : f.file_range()) | │ │ │ │ │ | { | │ │ │ │ │ -| // if we're using a proxy, we won't be able to accept any TCP | │ │ │ │ │ -| // connections. Not even uTP connections via the port we know about. | │ │ │ │ │ -| // The DHT may use the implied port to make it work, but the port we | │ │ │ │ │ -| // announce here has no relevance for that. | │ │ │ │ │ -| if (sock->flags & listen_socket_t::proxy) | │ │ │ │ │ -| return 0; | │ │ │ │ │ +| // files moved out to absolute paths are not moved | │ │ │ │ │ +| if (f.file_absolute_path(i)) continue; | │ │ │ │ │ | | │ │ │ │ │ -| if (!(sock->flags & listen_socket_t::accept_incoming)) | │ │ │ │ │ -| return 0; | │ │ │ │ │ +| if (has_parent_path(f.file_path(i))) | │ │ │ │ │ +| subdirs.insert(parent_path(f.file_path(i))); | │ │ │ │ │ | | │ │ │ │ │ -| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ -| } | │ │ │ │ │ +| // if we ended up renaming the file instead of moving it, there's no | │ │ │ │ │ +| // need to delete the source. | │ │ │ │ │ +| if (copied_files[i] == false) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| for (auto const& s : m_listen_sockets) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (!(s->flags & listen_socket_t::accept_incoming)) continue; | │ │ │ │ │ -| if (s->ssl == transport::plaintext) | │ │ │ │ │ -| return std::uint16_t(s->tcp_external_port()); | │ │ │ │ │ -| } | │ │ │ │ │ -|_ _ _r_e_t_u_r_n_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_5_5_5_ _ _|_t_h_i_s_ _f_u_n_c_t_i_o_n_ _s_h_o_u_l_d_ _b_e_ _r_e_m_o_v_e_d_ _a_n_d_ _u_s_e_r_s_ _n_e_e_d_ _t_o_ _d_e_a_l_ _w_i_t_h_ _t_h_e_ _m_o_r_e_ _g_e_n_e_r_i_c_ _c_a_s_e_ _o_f_ _h_a_v_i_n_g_ _m_u_l_t_i_p_l_e_ _s_s_l_ _p_o_r_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ffuunnccttiioonn sshhoouulldd bbee rreemmoovveedd aanndd uusseerrss nneeeedd ttoo ddeeaall wwiitthh tthhee mmoorree ggeenneerriicc ccaassee ooff hhaavviinngg mmuullttiippllee ssssll ppoorrttss ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55555555 ****** | │ │ │ │ │ -|return 0; | │ │ │ │ │ +| std::string const old_path = combine_path(save_path, f.file_path(i)); | │ │ │ │ │ | | │ │ │ │ │ -| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ +| // we may still have some files in old save_path | │ │ │ │ │ +| // eg. if (flags == dont_replace && exists(new_path)) | │ │ │ │ │ +| // ignore errors when removing | │ │ │ │ │ +| error_code ignore; | │ │ │ │ │ +| remove(old_path, ignore); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| for (auto const& s : m_listen_sockets) | │ │ │ │ │ +| for (std::string const& s : subdirs) | │ │ │ │ │ | { | │ │ │ │ │ -| if (!(s->flags & listen_socket_t::accept_incoming)) continue; | │ │ │ │ │ -| if (s->ssl == transport::plaintext) | │ │ │ │ │ -| return std::uint16_t(s->tcp_external_port()); | │ │ │ │ │ -| } | │ │ │ │ │ -| return 0; | │ │ │ │ │ -|#else | │ │ │ │ │ -| sock = m_listen_sockets.front().get(); | │ │ │ │ │ -| if (!(sock->flags & listen_socket_t::accept_incoming)) return 0; | │ │ │ │ │ -| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| error_code err; | │ │ │ │ │ +| std::string subdir = combine_path(save_path, s); | │ │ │ │ │ | | │ │ │ │ │ -|std::uint16_t session_impl::ssl_listen_port() const | │ │ │ │ │ +| while (!path_equal(subdir, save_path) && !err) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _ _r_e_m_o_v_e_(_s_u_b_d_i_r_,_ _e_r_r_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_4_8_6 |is this risky? The upper layer will assume we have the whole file. Perhaps we should verify that at least the size of the file is | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_c_o_r_r_e_c_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iiss tthhiiss rriisskkyy?? TThhee uuppppeerr llaayyeerr wwiillll aassssuummee wwee hhaavvee tthhee wwhhoollee ffiillee.. PPeerrhhaappss wwee sshhoouulldd vveerriiffyy tthhaatt aatt lleeaasstt tthhee ssiizzee ooff tthhee ffiillee iiss ccoorrrreecctt ********** | │ │ │ │ │ +|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::448866 ****** | │ │ │ │ │ |{ | │ │ │ │ │ -| return ssl_listen_port(nullptr); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| std::uint16_t session_impl::ssl_listen_port(listen_socket_t* sock) const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| if (sock) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (!(sock->flags & listen_socket_t::accept_incoming)) return 0; | │ │ │ │ │ -| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none | │ │ │ │ │ -| && m_settings.get_bool(settings_pack::proxy_peer_connections)) | │ │ │ │ │ -| return 0; | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const& s : m_listen_sockets) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (!(s->flags & listen_socket_t::accept_incoming)) continue; | │ │ │ │ │ -| if (s->ssl == transport::ssl) | │ │ │ │ │ -| return std::uint16_t(s->tcp_external_port()); | │ │ │ │ │ -| } | │ │ │ │ │ -|#else | │ │ │ │ │ -| TORRENT_UNUSED(sock); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| return 0; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|_ _i_n_t_ _s_e_s_s_i_o_n___i_m_p_l_:_:_g_e_t___l_i_s_t_e_n___p_o_r_t_(_t_r_a_n_s_p_o_r_t_ _c_o_n_s_t_ _s_s_l_,_ _a_u_x_:_:_l_i_s_t_e_n___s_o_c_k_e_t___h_a_n_d_l_e_ _c_o_n_s_t_&_ _s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_6_3_9_0_ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _b_e_ _f_a_c_t_o_r_e_d_ _i_n_t_o_ _t_h_e_ _u_d_p_ _s_o_c_k_e_t_,_ _s_o_ _w_e_ _o_n_l_y_ _h_a_v_e_ _t_h_e_ _c_o_d_e_ _o_n_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd bbee ffaaccttoorreedd iinnttoo tthhee uuddpp ssoocckkeett,, ssoo wwee oonnllyy hhaavvee tthhee ccooddee oonnccee ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::66339900 ****** | │ │ │ │ │ -|return upload_rate_limit(m_local_peer_class); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| int session_impl::local_download_rate_limit() const | │ │ │ │ │ -| { | │ │ │ │ │ -| return download_rate_limit(m_local_peer_class); | │ │ │ │ │ -| } | │ │ │ │ │ +| // we create directories lazily, so it's possible it hasn't | │ │ │ │ │ +| // been created yet. Create the directories now and try | │ │ │ │ │ +| // again | │ │ │ │ │ +| create_directories(parent_path(file_path), err); | │ │ │ │ │ | | │ │ │ │ │ -| int session_impl::upload_rate_limit_depr() const | │ │ │ │ │ -| { | │ │ │ │ │ -| return upload_rate_limit(m_global_class); | │ │ │ │ │ -| } | │ │ │ │ │ +| if (err) | │ │ │ │ │ +| { | │ │ │ │ │ +| ec.file(idx); | │ │ │ │ │ +| ec.operation = operation_t::mkdir; | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| int session_impl::download_rate_limit_depr() const | │ │ │ │ │ -| { | │ │ │ │ │ -| return download_rate_limit(m_global_class); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif // DEPRECATE | │ │ │ │ │ +| hard_link(s, file_path, err); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ +| // if the file already exists, that's not an error | │ │ │ │ │ +| if (err == boost::system::errc::file_exists) | │ │ │ │ │ +| continue; | │ │ │ │ │ | | │ │ │ │ │ -|void session_impl::update_peer_dscp() | │ │ │ │ │ +|if (err) | │ │ │ │ │ |{ | │ │ │ │ │ -| int const value = m_settings.get_int(settings_pack::peer_dscp); | │ │ │ │ │ -| for (auto const& l : m_listen_sockets) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (l->sock) | │ │ │ │ │ -| { | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| set_traffic_class(*l->sock, value, ec); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -| session_log(">>> SET_DSCP [ tcp (%s %d) value: %x e: %s ]" | │ │ │ │ │ -| , l->sock->local_endpoint().address().to_string().c_str() | │ │ │ │ │ -| , l->sock->local_endpoint().port(), value, ec.message().c_str()); | │ │ │ │ │ +| ec.ec = err; | │ │ │ │ │ +| ec.file(idx); | │ │ │ │ │ +| ec.operation = operation_t::file_hard_link; | │ │ │ │ │ +| return false; | │ │ │ │ │ | } | │ │ │ │ │ -|#endif | │ │ │ │ │ +| added_files = true; | │ │ │ │ │ +| stat.set_dirty(idx); | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -| if (l->udp_sock) | │ │ │ │ │ -| { | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| set_traffic_class(l->udp_sock->sock, value, ec); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -| session_log(">>> SET_DSCP [ udp (%s %d) value: %x e: %s ]" | │ │ │ │ │ -| , l->udp_sock->sock.local_endpoint().address().to_string().c_str() | │ │ │ │ │ -|_ _ _ _ _ _ _,_ _l_-_>_u_d_p___s_o_c_k_-_>_s_o_c_k_._l_o_c_a_l___p_o_r_t_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/ |support authentication here. tracker_req().auth | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_u_d_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_8_1_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssuuppppoorrtt aauutthheennttiiccaattiioonn hheerree.. ttrraacckkeerr__rreeqq(())..aauutthh ********** | │ │ │ │ │ -|****** ....//ssrrcc//uuddpp__ttrraacckkeerr__ccoonnnneeccttiioonn..ccpppp::8811 ****** | │ │ │ │ │ -|udp_tracker_connection::m_connection_cache; | │ │ │ │ │ -| | │ │ │ │ │ -| std::mutex udp_tracker_connection::m_cache_mutex; | │ │ │ │ │ -| | │ │ │ │ │ -| udp_tracker_connection::udp_tracker_connection( | │ │ │ │ │ -| io_context& ios | │ │ │ │ │ -| , tracker_manager& man | │ │ │ │ │ -| , tracker_request const& req | │ │ │ │ │ -| , std::weak_ptr c) | │ │ │ │ │ -| : tracker_connection(man, req, ios, std::move(c)) | │ │ │ │ │ -| , m_transaction_id(0) | │ │ │ │ │ -| , m_attempts(0) | │ │ │ │ │ -| , m_state(action_t::error) | │ │ │ │ │ -| , m_abort(false) | │ │ │ │ │ -| { | │ │ │ │ │ -| update_transaction_id(); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void udp_tracker_connection::start() | │ │ │ │ │ -| { | │ │ │ │ │ -|std::string hostname; | │ │ │ │ │ -|std::string protocol; | │ │ │ │ │ -| int port; | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| | │ │ │ │ │ -| std::tie(protocol, std::ignore, hostname, port, std::ignore) | │ │ │ │ │ -| = parse_url_components(tracker_req().url, ec); | │ │ │ │ │ -| if (port == -1) port = protocol == "http" ? 80 : 443; | │ │ │ │ │ -| | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| tracker_connection::fail(ec, operation_t::parse_address); | │ │ │ │ │ -| return; | │ │ │ │ │ | } | │ │ │ │ │ +|#endif // TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ | | │ │ │ │ │ -| aux::session_settings const& settings = m_man.settings(); | │ │ │ │ │ -| | │ │ │ │ │ -| int const proxy_type = settings.get_int(settings_pack::proxy_type); | │ │ │ │ │ +| bool const seed = (rd.have_pieces.size() >= fs.num_pieces() | │ │ │ │ │ +| && rd.have_pieces.all_set()) | │ │ │ │ │ +| || (rd.flags & torrent_flags::seed_mode); | │ │ │ │ │ | | │ │ │ │ │ -| if (settings.get_bool(settings_pack::proxy_hostnames) | │ │ │ │ │ -| && (proxy_type == settings_pack::socks5 | │ │ │ │ │ -| || proxy_type == settings_pack::socks5_pw)) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_hostname = hostname; | │ │ │ │ │ -| m_target.port(std::uint16_t(port)); | │ │ │ │ │ -| start_announce(); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ +| if (seed) | │ │ │ │ │ | { | │ │ │ │ │ -| using namespace std::placeholders; | │ │ │ │ │ -|_ _ _ _A_D_D___O_U_T_S_T_A_N_D_I_N_G___A_S_Y_N_C_(_"_u_d_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_:_:_n_a_m_e___l_o_o_k_u_p_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_a_l_e_r_t___m_a_n_a_g_e_r_._c_p_p_:_8_0_ _ _ _|_k_e_e_p_ _a_ _c_o_u_n_t_ _o_f_ _t_h_e_ _n_u_m_b_e_r_ _o_f_ _t_h_r_e_a_d_s_ _w_a_i_t_i_n_g_._ _O_n_l_y_ _i_f_ _i_t_'_s_ _>_ _0_ _n_o_t_i_f_y_ _t_h_e_m_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** kkeeeepp aa ccoouunntt ooff tthhee nnuummbbeerr ooff tthhrreeaaddss wwaaiittiinngg.. OOnnllyy iiff iitt''ss >> 00 nnoottiiffyy tthheemm ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt__mmaannaaggeerr..ccpppp::8800 ****** | │ │ │ │ │ -|return m_alerts[m_generation].front(); | │ │ │ │ │ +| for (file_index_t const file_index : fs.file_range()) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (fs.pad_file_at(file_index)) continue; | │ │ │ │ │ | | │ │ │ │ │ -| // this call can be interrupted prematurely by other signals | │ │ │ │ │ -| m_condition.wait_for(lock, max_wait); | │ │ │ │ │ -| if (!m_alerts[m_generation].empty()) | │ │ │ │ │ -| return m_alerts[m_generation].front(); | │ │ │ │ │ +| // files with priority zero may not have been saved to disk at their | │ │ │ │ │ +| // expected location, but is likely to be in a partfile. Just exempt it | │ │ │ │ │ +| // from checking | │ │ │ │ │ +| if (file_index < file_priority.end_index() | │ │ │ │ │ +| && file_priority[file_index] == dont_download | │ │ │ │ │ +| && !(rd.flags & torrent_flags::seed_mode)) | │ │ │ │ │ +|_ _ _ _ _ _c_o_n_t_i_n_u_e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_2_0_2_1_ _ _ _ _ _ _ _ _ _|_t_h_e_ _s_a_l_t_ _h_e_r_e_ _i_s_ _a_l_l_o_c_a_t_e_d_ _o_n_ _t_h_e_ _h_e_a_p_._ _I_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _a_l_l_o_c_a_t_e_ _i_n_ _t_h_e_ _s_t_a_c_k___a_l_l_o_c_a_t_o_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhee ssaalltt hheerree iiss aallllooccaatteedd oonn tthhee hheeaapp.. IItt wwoouulldd bbee nniiccee ttoo aallllooccaattee iinn tthhee ssttaacckk__aallllooccaattoorr ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::22002211 ****** | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| return nullptr; | │ │ │ │ │ -| } | │ │ │ │ │ +| dht_immutable_item_alert::dht_immutable_item_alert(aux::stack_allocator& | │ │ │ │ │ +| , sha1_hash const& t, entry i) | │ │ │ │ │ +| : target(t), item(std::move(i)) | │ │ │ │ │ +| {} | │ │ │ │ │ | | │ │ │ │ │ -| void alert_manager::maybe_notify(alert* a) | │ │ │ │ │ +| std::string dht_immutable_item_alert::message() const | │ │ │ │ │ | { | │ │ │ │ │ -| if (m_alerts[m_generation].size() == 1) | │ │ │ │ │ -| { | │ │ │ │ │ -| // we just posted to an empty queue. If anyone is waiting for | │ │ │ │ │ -| // alerts, we need to notify them. Also (potentially) call the | │ │ │ │ │ -| // user supplied m_notify callback to let the client wake up its | │ │ │ │ │ -| // message loop to poll for alerts. | │ │ │ │ │ -| if (m_notify) m_notify(); | │ │ │ │ │ -| | │ │ │ │ │ -|m_condition.notify_all(); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ -| for (auto& e : m_ses_extensions) | │ │ │ │ │ -| e->on_alert(a); | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ |#else | │ │ │ │ │ -| TORRENT_UNUSED(a); | │ │ │ │ │ +| char msg[1050]; | │ │ │ │ │ +| std::snprintf(msg, sizeof(msg), "DHT immutable item %s [ %s ]" | │ │ │ │ │ +| , aux::to_hex(target).c_str() | │ │ │ │ │ +| , item.to_string().c_str()); | │ │ │ │ │ +| return msg; | │ │ │ │ │ |#endif | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void alert_manager::set_notify_function(std::function const& fun) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::unique_lock lock(m_mutex); | │ │ │ │ │ -| m_notify = fun; | │ │ │ │ │ -| if (!m_alerts[m_generation].empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_notify) m_notify(); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ +|dht_mutable_item_alert::dht_mutable_item_alert(aux::stack_allocator& | │ │ │ │ │ +|, std::array const& k | │ │ │ │ │ +| , std::array const& sig | │ │ │ │ │ +| , std::int64_t sequence | │ │ │ │ │ +| , string_view s | │ │ │ │ │ +| , entry i | │ │ │ │ │ +| , bool a) | │ │ │ │ │ +| : key(k), signature(sig), seq(sequence), salt(s), item(std::move(i)), authoritative(a) | │ │ │ │ │ +| {} | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ -| void alert_manager::add_extension(std::shared_ptr ext) | │ │ │ │ │ +| std::string dht_mutable_item_alert::message() const | │ │ │ │ │ | { | │ │ │ │ │ -| m_ses_extensions.push_back(std::move(ext)); | │ │ │ │ │ -| } | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char msg[1050]; | │ │ │ │ │ +| std::snprintf(msg, sizeof(msg), "DHT mutable item (key=%s salt=%s seq=%" PRId64 " %s) [ %s ]" | │ │ │ │ │ +| , aux::to_hex(key).c_str() | │ │ │ │ │ +| , salt.c_str() | │ │ │ │ │ +| , seq | │ │ │ │ │ +| , authoritative ? "auth" : "non-auth" | │ │ │ │ │ +| , item.to_string().c_str()); | │ │ │ │ │ +| return msg; | │ │ │ │ │ |#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| void alert_manager::get_all(std::vector& alerts) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _s_t_d_:_:_l_o_c_k___g_u_a_r_d_<_s_t_d_:_:_r_e_c_u_r_s_i_v_e___m_u_t_e_x_>_ _l_o_c_k_(_m___m_u_t_e_x_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| dht_put_alert::dht_put_alert(aux::stack_allocator&, sha1_hash const& t, int n) | │ │ │ │ │ +| : target(t) | │ │ │ │ │ +| , public_key() | │ │ │ │ │ +| , signature() | │ │ │ │ │ +|_ _ _,_ _s_a_l_t_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 2|_._._/_s_r_c_/ |peer_connection and tracker_connection should probably be flags | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_i_n_s_t_a_n_t_i_a_t_e___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_4_4_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ppeeeerr__ccoonnnneeccttiioonn aanndd ttrraacckkeerr__ccoonnnneeccttiioonn sshhoouulldd pprroobbaabbllyy bbee ffllaaggss ********** | │ │ │ │ │ |****** ....//ssrrcc//iinnssttaannttiiaattee__ccoonnnneeccttiioonn..ccpppp::4444 ****** | │ │ │ │ │ |ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | │ │ │ │ │ |LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | │ │ │ │ │ |CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | │ │ │ │ │ @@ -2936,233 +2522,502 @@ │ │ │ │ │ | s.set_impl(sm->new_utp_socket(&s)); | │ │ │ │ │ | return socket_type(std::move(s)); | │ │ │ │ │ | } | │ │ │ │ │ | } | │ │ │ │ │ |#if TORRENT_USE_I2P | │ │ │ │ │ | else if (ps.type == settings_pack::i2p_proxy) | │ │ │ │ │ |_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_2_0_2_1_ _ _ _ _ _ _ _ _ _|_t_h_e_ _s_a_l_t_ _h_e_r_e_ _i_s_ _a_l_l_o_c_a_t_e_d_ _o_n_ _t_h_e_ _h_e_a_p_._ _I_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _a_l_l_o_c_a_t_e_ _i_n_ _t_h_e_ _s_t_a_c_k___a_l_l_o_c_a_t_o_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhee ssaalltt hheerree iiss aallllooccaatteedd oonn tthhee hheeaapp.. IItt wwoouulldd bbee nniiccee ttoo aallllooccaattee iinn tthhee ssttaacckk__aallllooccaattoorr ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::22002211 ****** | │ │ │ │ │ -|} | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_5_0_4_ _ _ _ _ _ _ _ _|_p_o_s_t_ _a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ppoosstt aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::550044 ****** | │ │ │ │ │ +|if (m_current_gauge_state != no_gauge_state) | │ │ │ │ │ +| inc_stats_counter(m_current_gauge_state + counters::num_checking_torrents, -1); | │ │ │ │ │ +| if (new_gauge_state != no_gauge_state) | │ │ │ │ │ +| inc_stats_counter(new_gauge_state + counters::num_checking_torrents, 1); | │ │ │ │ │ | | │ │ │ │ │ -| dht_immutable_item_alert::dht_immutable_item_alert(aux::stack_allocator& | │ │ │ │ │ -| , sha1_hash const& t, entry i) | │ │ │ │ │ -| : target(t), item(std::move(i)) | │ │ │ │ │ -| {} | │ │ │ │ │ +| TORRENT_ASSERT(new_gauge_state >= 0); | │ │ │ │ │ +| TORRENT_ASSERT(new_gauge_state <= no_gauge_state); | │ │ │ │ │ +| m_current_gauge_state = static_cast(new_gauge_state); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| std::string dht_immutable_item_alert::message() const | │ │ │ │ │ +| void torrent::leave_seed_mode(seed_mode_t const checking) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char msg[1050]; | │ │ │ │ │ -| std::snprintf(msg, sizeof(msg), "DHT immutable item %s [ %s ]" | │ │ │ │ │ -| , aux::to_hex(target).c_str() | │ │ │ │ │ -| , item.to_string().c_str()); | │ │ │ │ │ -| return msg; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| if (!m_seed_mode) return; | │ │ │ │ │ | | │ │ │ │ │ -|dht_mutable_item_alert::dht_mutable_item_alert(aux::stack_allocator& | │ │ │ │ │ -|, std::array const& k | │ │ │ │ │ -| , std::array const& sig | │ │ │ │ │ -| , std::int64_t sequence | │ │ │ │ │ -| , string_view s | │ │ │ │ │ -| , entry i | │ │ │ │ │ -| , bool a) | │ │ │ │ │ -| : key(k), signature(sig), seq(sequence), salt(s), item(std::move(i)), authoritative(a) | │ │ │ │ │ -| {} | │ │ │ │ │ +| if (checking == seed_mode_t::check_files) | │ │ │ │ │ +| { | │ │ │ │ │ +| // this means the user promised we had all the | │ │ │ │ │ +| // files, but it turned out we didn't. This is | │ │ │ │ │ +| // an error. | │ │ │ │ │ | | │ │ │ │ │ -| std::string dht_mutable_item_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char msg[1050]; | │ │ │ │ │ -| std::snprintf(msg, sizeof(msg), "DHT mutable item (key=%s salt=%s seq=%" PRId64 " %s) [ %s ]" | │ │ │ │ │ -| , aux::to_hex(key).c_str() | │ │ │ │ │ -| , salt.c_str() | │ │ │ │ │ -| , seq | │ │ │ │ │ -| , authoritative ? "auth" : "non-auth" | │ │ │ │ │ -| , item.to_string().c_str()); | │ │ │ │ │ -| return msg; | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| debug_log("*** FAILED SEED MODE, rechecking"); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| debug_log("*** LEAVING SEED MODE (%s)" | │ │ │ │ │ +| , checking == seed_mode_t::skip_checking ? "as seed" : "as non-seed"); | │ │ │ │ │ |#endif | │ │ │ │ │ +| m_seed_mode = false; | │ │ │ │ │ +| // seed is false if we turned out not | │ │ │ │ │ +| // to be a seed after all | │ │ │ │ │ +| if (checking == seed_mode_t::check_files | │ │ │ │ │ +| && state() != torrent_status::checking_resume_data) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_have_all = false; | │ │ │ │ │ +| set_state(torrent_status::downloading); | │ │ │ │ │ +| force_recheck(); | │ │ │ │ │ +| } | │ │ │ │ │ +| m_num_verified = 0; | │ │ │ │ │ +| m_verified.clear(); | │ │ │ │ │ +| m_verifying.clear(); | │ │ │ │ │ +| | │ │ │ │ │ +| set_need_save_resume(torrent_handle::if_state_changed); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| dht_put_alert::dht_put_alert(aux::stack_allocator&, sha1_hash const& t, int n) | │ │ │ │ │ -| : target(t) | │ │ │ │ │ -| , public_key() | │ │ │ │ │ -| , signature() | │ │ │ │ │ -|_ _ _,_ _s_a_l_t_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -| | |technically, this is where the transaction of moving the files is completed. This is where the new save_path should be committed. If| │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_2_9_4 |there is an error in the code below, that should not prevent the new save path to be set. Maybe it would make sense to make the | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_s_a_v_e___p_a_t_h_ _a_n_ _i_n_-_o_u_t_ _p_a_r_a_m_e_t_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteecchhnniiccaallllyy,, tthhiiss iiss wwhheerree tthhee ttrraannssaaccttiioonn ooff mmoovviinngg tthhee ffiilleess iiss ccoommpplleetteedd.. TThhiiss iiss wwhheerree tthhee nneeww ssaavvee__ppaatthh sshhoouulldd bbee ccoommmmiitttteedd.. IIff tthheerree iiss aann eerrrroorr iinn tthhee ccooddee bbeellooww,,| │ │ │ │ │ -|tthhaatt sshhoouulldd nnoott pprreevveenntt tthhee nneeww ssaavvee ppaatthh ttoo bbee sseett.. MMaayybbee iitt wwoouulldd mmaakkee sseennssee ttoo mmaakkee tthhee ssaavvee__ppaatthh aann iinn--oouutt ppaarraammeetteerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::229944 ****** | │ │ │ │ │ -|while (--file_index >= file_index_t(0)) | │ │ │ │ │ +| void torrent::verified(piece_index_t const piece) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(!m_verified.get_bit(piece)); | │ │ │ │ │ +|_ _ _+_+_m___n_u_m___v_e_r_i_f_i_e_d_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_8_5_2_ _ _ _ _ _ _ _|_a_d_d_ _a_ _u_n_i_t_ _t_e_s_t_ _w_h_e_r_e_ _w_e_ _d_o_n_'_t_ _h_a_v_e_ _m_e_t_a_d_a_t_a_,_ _c_o_n_n_e_c_t_ _t_o_ _a_ _p_e_e_r_ _t_h_a_t_ _s_e_n_d_s_ _a_ _b_i_t_f_i_e_l_d_ _t_h_a_t_'_s_ _t_o_o_ _l_a_r_g_e_,_ _t_h_e_n_ _w_e_ _g_e_t_ _t_h_e_ _m_e_t_a_d_a_t_a_ _ _ _ | │ │ │ │ │ +|********** aadddd aa uunniitt tteesstt wwhheerree wwee ddoonn''tt hhaavvee mmeettaaddaattaa,, ccoonnnneecctt ttoo aa ppeeeerr tthhaatt sseennddss aa bbiittffiieelldd tthhaatt''ss ttoooo llaarrggee,, tthheenn wwee ggeett tthhee mmeettaaddaattaa ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11885522 ****** | │ │ │ │ │ +|for (auto const& f : m_add_torrent_params->renamed_files) | │ │ │ │ │ | { | │ │ │ │ │ -| // files moved out to absolute paths are not moved | │ │ │ │ │ -| if (f.file_absolute_path(file_index)) continue; | │ │ │ │ │ +| if (f.first < file_index_t(0) || f.first >= fs.end_file()) continue; | │ │ │ │ │ +| m_torrent_file->rename_file(file_index_t(f.first), f.second); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // if we ended up copying the file, don't do anything during | │ │ │ │ │ -| // roll-back | │ │ │ │ │ -| if (copied_files[file_index]) continue; | │ │ │ │ │ +| construct_storage(); | │ │ │ │ │ | | │ │ │ │ │ -| std::string const old_path = combine_path(save_path, f.file_path(file_index)); | │ │ │ │ │ -| std::string const new_path = combine_path(new_save_path, f.file_path(file_index)); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_SHARE_MODE | │ │ │ │ │ +| if (m_share_mode && valid_metadata()) | │ │ │ │ │ +| { | │ │ │ │ │ +| // in share mode, all pieces have their priorities initialized to 0 | │ │ │ │ │ +| m_file_priority.clear(); | │ │ │ │ │ +| m_file_priority.resize(m_torrent_file->num_files(), dont_download); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| // ignore errors when rolling back | │ │ │ │ │ -| storage_error ignore; | │ │ │ │ │ -| move_file(new_path, old_path, ignore); | │ │ │ │ │ +| // it's important to initialize the peers early, because this is what will | │ │ │ │ │ +| // fix up their have-bitmasks to have the correct size | │ │ │ │ │ +|if (!m_connections_initialized) | │ │ │ │ │ +|{ | │ │ │ │ │ +| m_connections_initialized = true; | │ │ │ │ │ +| // all peer connections have to initialize themselves now that the metadata | │ │ │ │ │ +| // is available | │ │ │ │ │ +| // copy the peer list since peers may disconnect and invalidate | │ │ │ │ │ +| // m_connections as we initialize them | │ │ │ │ │ +| for (auto c : m_connections) | │ │ │ │ │ +| { | │ │ │ │ │ +| auto pc = c->self(); | │ │ │ │ │ +| if (pc->is_disconnecting()) continue; | │ │ │ │ │ +| pc->on_metadata_impl(); | │ │ │ │ │ +| if (pc->is_disconnecting()) continue; | │ │ │ │ │ +| pc->init(); | │ │ │ │ │ | } | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| return { status_t::fatal_disk_error, save_path }; | │ │ │ │ │ +| // in case file priorities were passed in via the add_torrent_params | │ │ │ │ │ +| // and also in the case of share mode, we need to update the priorities | │ │ │ │ │ +| // this has to be applied before piece priority | │ │ │ │ │ +| if (!m_file_priority.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| // m_file_priority was loaded from the resume data, this doesn't | │ │ │ │ │ +| // alter any state that needs to be saved in the resume data | │ │ │ │ │ +| auto const ns = m_need_save_resume_data; | │ │ │ │ │ +| update_piece_priorities(m_file_priority); | │ │ │ │ │ +| m_need_save_resume_data = ns; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ +| if (m_add_torrent_params) | │ │ │ │ │ +|_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_4_9_2_ _ _ _ _ _ _ _|_u_s_e_ _c_h_r_o_n_o_ _t_y_p_e_ _f_o_r_ _t_i_m_e_ _d_u_r_a_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee cchhrroonnoo ttyyppee ffoorr ttiimmee dduurraattiioonn ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44449922 ****** | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -|std::set subdirs; | │ │ │ │ │ -| for (auto const i : f.file_range()) | │ │ │ │ │ +| m_picker->piece_passed(index); | │ │ │ │ │ +| update_gauge(); | │ │ │ │ │ +| we_have(index); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| debug_log("we_have(%d) (num_have: %d)", int(index), num_have()); | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_STREAMING | │ │ │ │ │ +| remove_time_critical_piece(index, true); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_PREDICTIVE_PIECES | │ │ │ │ │ +| // we believe we will complete this piece very soon | │ │ │ │ │ +| // announce it to peers ahead of time to eliminate the | │ │ │ │ │ +| // round-trip times involved in announcing it, requesting it | │ │ │ │ │ +| // and sending it | │ │ │ │ │ +|void torrent::predicted_have_piece(piece_index_t const index, int const milliseconds) | │ │ │ │ │ +|{ | │ │ │ │ │ +| auto const i = std::lower_bound(m_predictive_pieces.begin() | │ │ │ │ │ +| , m_predictive_pieces.end(), index); | │ │ │ │ │ +| if (i != m_predictive_pieces.end() && *i == index) return; | │ │ │ │ │ +| | │ │ │ │ │ +| for (auto p : m_connections) | │ │ │ │ │ | { | │ │ │ │ │ -| // files moved out to absolute paths are not moved | │ │ │ │ │ -| if (f.file_absolute_path(i)) continue; | │ │ │ │ │ +| TORRENT_INCREMENT(m_iterating_connections); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| p->peer_log(peer_log_alert::outgoing, "PREDICTIVE_HAVE", "piece: %d expected in %d ms" | │ │ │ │ │ +| , static_cast(index), milliseconds); | │ │ │ │ │ +|#else | │ │ │ │ │ +| TORRENT_UNUSED(milliseconds); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| p->announce_piece(index); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (has_parent_path(f.file_path(i))) | │ │ │ │ │ -| subdirs.insert(parent_path(f.file_path(i))); | │ │ │ │ │ +| m_predictive_pieces.insert(i, index); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| // if we ended up renaming the file instead of moving it, there's no | │ │ │ │ │ -| // need to delete the source. | │ │ │ │ │ -| if (copied_files[i] == false) continue; | │ │ │ │ │ +| // blocks may contain the block indices of the blocks that failed (if this is | │ │ │ │ │ +| // a v2 torrent). | │ │ │ │ │ +| void torrent::piece_failed(piece_index_t const index, std::vector blocks) | │ │ │ │ │ +| { | │ │ │ │ │ +| // if the last piece fails the peer connection will still | │ │ │ │ │ +| // think that it has received all of it until this function | │ │ │ │ │ +| // resets the download queue. So, we cannot do the | │ │ │ │ │ +| // invariant check here since it assumes: | │ │ │ │ │ +|_ _ _/_/_ _(_t_o_t_a_l___d_o_n_e_ _=_=_ _m___t_o_r_r_e_n_t___f_i_l_e_-_>_t_o_t_a_l___s_i_z_e_(_)_)_ _=_>_ _i_s___s_e_e_d_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_9_1_9_ _ _ _ _ _ _ _|_a_b_o_r_t_ _l_o_o_k_u_p_s_ _t_h_i_s_ _t_o_r_r_e_n_t_ _h_a_s_ _m_a_d_e_ _v_i_a_ _t_h_e_ _s_e_s_s_i_o_n_ _h_o_s_t_ _r_e_s_o_l_v_e_r_ _i_n_t_e_r_f_a_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aabboorrtt llooookkuuppss tthhiiss ttoorrrreenntt hhaass mmaaddee vviiaa tthhee sseessssiioonn hhoosstt rreessoollvveerr iinntteerrffaaccee ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44991199 ****** | │ │ │ │ │ +|TORRENT_UNUSED(e); | │ │ │ │ │ +| m_storage.reset(); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| debug_log("Failed to flush disk cache: %s", e.what()); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| // clients may rely on this alert to be posted, so it's probably a | │ │ │ │ │ +| // good idea to post it here, even though we failed | │ │ │ │ │ +| if (alerts().should_post()) | │ │ │ │ │ +| alerts().emplace_alert(get_handle()); | │ │ │ │ │ +| } | │ │ │ │ │ +| m_ses.deferred_submit_jobs(); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| if (alerts().should_post()) | │ │ │ │ │ +| alerts().emplace_alert(get_handle()); | │ │ │ │ │ +| alerts().emplace_alert(get_handle() | │ │ │ │ │ +| , info_hash(), get_userdata()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| std::string const old_path = combine_path(save_path, f.file_path(i)); | │ │ │ │ │ | | │ │ │ │ │ -| // we may still have some files in old save_path | │ │ │ │ │ -| // eg. if (flags == dont_replace && exists(new_path)) | │ │ │ │ │ -| // ignore errors when removing | │ │ │ │ │ -| error_code ignore; | │ │ │ │ │ -| remove(old_path, ignore); | │ │ │ │ │ +|if (!m_apply_ip_filter) | │ │ │ │ │ +| { | │ │ │ │ │ +| inc_stats_counter(counters::non_filter_torrents, -1); | │ │ │ │ │ +| m_apply_ip_filter = true; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| for (std::string const& s : subdirs) | │ │ │ │ │ +| m_paused = false; | │ │ │ │ │ +| m_auto_managed = false; | │ │ │ │ │ +| update_state_list(); | │ │ │ │ │ +| for (torrent_list_index_t i{}; i != m_links.end_index(); ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| error_code err; | │ │ │ │ │ -| std::string subdir = combine_path(save_path, s); | │ │ │ │ │ +| if (!m_links[i].in_list()) continue; | │ │ │ │ │ +| m_links[i].unlink(m_ses.torrent_list(i), i); | │ │ │ │ │ +| } | │ │ │ │ │ +| // don't re-add this torrent to the state-update list | │ │ │ │ │ +| m_state_subscription = false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| while (!path_equal(subdir, save_path) && !err) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _ _r_e_m_o_v_e_(_s_u_b_d_i_r_,_ _e_r_r_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_4_8_6 |is this risky? The upper layer will assume we have the whole file. Perhaps we should verify that at least the size of the file is | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_c_o_r_r_e_c_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iiss tthhiiss rriisskkyy?? TThhee uuppppeerr llaayyeerr wwiillll aassssuummee wwee hhaavvee tthhee wwhhoollee ffiillee.. PPeerrhhaappss wwee sshhoouulldd vveerriiffyy tthhaatt aatt lleeaasstt tthhee ssiizzee ooff tthhee ffiillee iiss ccoorrrreecctt ********** | │ │ │ │ │ -|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::448866 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| // we create directories lazily, so it's possible it hasn't | │ │ │ │ │ -| // been created yet. Create the directories now and try | │ │ │ │ │ -| // again | │ │ │ │ │ -| create_directories(parent_path(file_path), err); | │ │ │ │ │ +| // this is called when we're destructing non-gracefully. i.e. we're _just_ | │ │ │ │ │ +| // destructing everything. | │ │ │ │ │ +| void torrent::panic() | │ │ │ │ │ +| { | │ │ │ │ │ +| m_storage.reset(); | │ │ │ │ │ +| // if there are any other peers allocated still, we need to clear them | │ │ │ │ │ +| // now. They can't be cleared later because the allocator will already | │ │ │ │ │ +| // have been destructed | │ │ │ │ │ +| if (m_peer_list) m_peer_list->clear(); | │ │ │ │ │ +| m_connections.clear(); | │ │ │ │ │ +| m_outgoing_pids.clear(); | │ │ │ │ │ +|_ _ _m___p_e_e_r_s___t_o___d_i_s_c_o_n_n_e_c_t_._c_l_e_a_r_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_8_0_3_2 |if peer is a really good peer, maybe we shouldn't disconnect it perhaps this logic should be disabled if we have too many idle peers| │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_(_w_i_t_h_ _s_o_m_e_ _d_e_f_i_n_i_t_i_o_n_ _o_f_ _i_d_l_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iiff ppeeeerr iiss aa rreeaallllyy ggoooodd ppeeeerr,, mmaayybbee wwee sshhoouullddnn''tt ddiissccoonnnneecctt iitt ppeerrhhaappss tthhiiss llooggiicc sshhoouulldd bbee ddiissaabblleedd iiff wwee hhaavvee ttoooo mmaannyy iiddllee ppeeeerrss ((wwiitthh ssoommee ddeeffiinniittiioonn ooff iiddllee)) **********| │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::88003322 ****** | │ │ │ │ │ +| m_peers_to_disconnect.reserve(m_connections.size() + 1); | │ │ │ │ │ +| m_connections.reserve(m_connections.size() + 1); | │ │ │ │ │ | | │ │ │ │ │ -| if (err) | │ │ │ │ │ -| { | │ │ │ │ │ -| ec.file(idx); | │ │ │ │ │ -| ec.operation = operation_t::mkdir; | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| TORRENT_ASSERT(p->remote() == p->get_socket().remote_endpoint(ec) || ec); | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| hard_link(s, file_path, err); | │ │ │ │ │ -| } | │ │ │ │ │ +| TORRENT_ASSERT(p->peer_info_struct() != nullptr); | │ │ │ │ │ | | │ │ │ │ │ -| // if the file already exists, that's not an error | │ │ │ │ │ -| if (err == boost::system::errc::file_exists) | │ │ │ │ │ -| continue; | │ │ │ │ │ +| // we need to do this after we've added the peer to the peer_list | │ │ │ │ │ +| // since that's when the peer is assigned its peer_info object, | │ │ │ │ │ +| // which holds the rank | │ │ │ │ │ +| if (maybe_replace_peer) | │ │ │ │ │ +| { | │ │ │ │ │ +| // now, find the lowest rank peer and disconnect that | │ │ │ │ │ +| // if it's lower rank than the incoming connection | │ │ │ │ │ +| peer_connection* peer = find_lowest_ranking_peer(); | │ │ │ │ │ | | │ │ │ │ │ -|if (err) | │ │ │ │ │ +|if (peer != nullptr && peer->peer_rank() < p->peer_rank()) | │ │ │ │ │ |{ | │ │ │ │ │ -| ec.ec = err; | │ │ │ │ │ -| ec.file(idx); | │ │ │ │ │ -| ec.operation = operation_t::file_hard_link; | │ │ │ │ │ -| return false; | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| { | │ │ │ │ │ +| debug_log("CLOSING CONNECTION \"%s\" peer list full (low peer rank) " | │ │ │ │ │ +| "connections: %d limit: %d" | │ │ │ │ │ +| , print_endpoint(peer->remote()).c_str() | │ │ │ │ │ +| , num_peers() | │ │ │ │ │ +| , m_max_connections); | │ │ │ │ │ | } | │ │ │ │ │ -| added_files = true; | │ │ │ │ │ -| stat.set_dirty(idx); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| peer->disconnect(errors::too_many_connections, operation_t::bittorrent); | │ │ │ │ │ +| p->peer_disconnected_other(); | │ │ │ │ │ | } | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif // TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| { | │ │ │ │ │ +| debug_log("CLOSING CONNECTION \"%s\" peer list full (low peer rank) " | │ │ │ │ │ +| "connections: %d limit: %d" | │ │ │ │ │ +| , print_endpoint(p->remote()).c_str() | │ │ │ │ │ +| , num_peers() | │ │ │ │ │ +| , m_max_connections); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| p->disconnect(errors::too_many_connections, operation_t::bittorrent); | │ │ │ │ │ +| // we have to do this here because from the peer's point of view | │ │ │ │ │ +| // it wasn't really attached to the torrent, but we do need | │ │ │ │ │ +|_ _ _ _ _/_/_ _t_o_ _l_e_t_ _p_e_e_r___l_i_s_t_ _k_n_o_w_ _w_e_'_r_e_ _r_e_m_o_v_i_n_g_ _i_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/ |just make this peer not have the pieces associated with the file we just requested. Only when it doesn't have any of the file do the| │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_w_e_b___p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_6_2_6_ _ _ _|_f_o_l_l_o_w_i_n_g_ _p_a_d_ _f_i_l_e_s_ _w_i_l_l_ _m_a_k_e_ _i_t_ _c_o_m_p_l_i_c_a_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** jjuusstt mmaakkee tthhiiss ppeeeerr nnoott hhaavvee tthhee ppiieecceess aassssoocciiaatteedd wwiitthh tthhee ffiillee wwee jjuusstt rreeqquueesstteedd.. OOnnllyy wwhheenn iitt ddooeessnn''tt hhaavvee aannyy ooff tthhee ffiillee ddoo tthhee ffoolllloowwiinngg ppaadd ffiilleess wwiillll mmaakkee iitt | │ │ │ │ │ +|ccoommpplliiccaatteedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//wweebb__ppeeeerr__ccoonnnneeccttiioonn..ccpppp::662266 ****** | │ │ │ │ │ +| peer_connection::received_invalid_data(index, single_peer); | │ │ │ │ │ | | │ │ │ │ │ -| bool const seed = (rd.have_pieces.size() >= fs.num_pieces() | │ │ │ │ │ -| && rd.have_pieces.all_set()) | │ │ │ │ │ -| || (rd.flags & torrent_flags::seed_mode); | │ │ │ │ │ +| // if we don't think we have any of the files, allow banning the web seed | │ │ │ │ │ +| if (num_have_pieces() == 0) return true; | │ │ │ │ │ | | │ │ │ │ │ -| if (seed) | │ │ │ │ │ -| { | │ │ │ │ │ -| for (file_index_t const file_index : fs.file_range()) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (fs.pad_file_at(file_index)) continue; | │ │ │ │ │ +| // don't disconnect, we won't request anything from this file again | │ │ │ │ │ +| return false; | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| // files with priority zero may not have been saved to disk at their | │ │ │ │ │ -| // expected location, but is likely to be in a partfile. Just exempt it | │ │ │ │ │ -| // from checking | │ │ │ │ │ -| if (file_index < file_priority.end_index() | │ │ │ │ │ -| && file_priority[file_index] == dont_download | │ │ │ │ │ -| && !(rd.flags & torrent_flags::seed_mode)) | │ │ │ │ │ -|_ _ _ _ _ _c_o_n_t_i_n_u_e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_e_s_c_a_p_e___s_t_r_i_n_g_._c_p_p_:_1_9_4_ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _m_o_v_e_d_ _i_n_t_o_ _s_t_r_i_n_g___u_t_i_l_._c_p_p_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd pprroobbaabbllyy bbee mmoovveedd iinnttoo ssttrriinngg__uuttiill..ccpppp ********** | │ │ │ │ │ -|****** ....//ssrrcc//eessccaappee__ssttrriinngg..ccpppp::119944 ****** | │ │ │ │ │ +|void web_peer_connection::on_receive_padfile() | │ │ │ │ │ |{ | │ │ │ │ │ -| return escape_string_impl(str.data(), int(str.size()), 10); | │ │ │ │ │ -| } | │ │ │ │ │ +| handle_padfile(); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| bool need_encoding(char const* str, int const len) | │ │ │ │ │ +|void web_peer_connection::handle_error(int const bytes_left) | │ │ │ │ │ +|{ | │ │ │ │ │ +| std::shared_ptr t = associated_torrent().lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|// temporarily unavailable, retry later | │ │ │ │ │ +| t->retry_web_seed(this, m_parser.header_duration("retry-after")); | │ │ │ │ │ +| if (t->alerts().should_post()) | │ │ │ │ │ | { | │ │ │ │ │ -| for (int i = 0; i < len; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (std::strchr(unreserved_chars, *str) == nullptr || *str == 0) | │ │ │ │ │ -| return true; | │ │ │ │ │ -| ++str; | │ │ │ │ │ -| } | │ │ │ │ │ -| return false; | │ │ │ │ │ +| std::string const error_msg = to_string(m_parser.status_code()).data() | │ │ │ │ │ +| + (" " + m_parser.message()); | │ │ │ │ │ +| t->alerts().emplace_alert(t->get_handle(), m_url | │ │ │ │ │ +| , error_msg); | │ │ │ │ │ | } | │ │ │ │ │ +| received_bytes(0, bytes_left); | │ │ │ │ │ +| disconnect(error_code(m_parser.status_code(), http_category()), operation_t::bittorrent, failure); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| void convert_path_to_posix(std::string& path) | │ │ │ │ │ +|void web_peer_connection::disable(error_code const& ec) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // we should not try this server again. | │ │ │ │ │ +| m_web->disabled = true; | │ │ │ │ │ +| disconnect(ec, operation_t::bittorrent, peer_error); | │ │ │ │ │ +| if (m_web->ephemeral) | │ │ │ │ │ | { | │ │ │ │ │ -| std::replace(path.begin(), path.end(), '\\', '/'); | │ │ │ │ │ +| std::shared_ptr t = associated_torrent().lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ +| t->remove_web_seed_conn(this); | │ │ │ │ │ | } | │ │ │ │ │ +| m_web = nullptr; | │ │ │ │ │ +| TORRENT_ASSERT(is_disconnecting()); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -|std::string read_until(char const*& str, char const delim, char const* end) | │ │ │ │ │ +|void web_peer_connection::handle_redirect(int const bytes_left) | │ │ │ │ │ +|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/_p_e_e_r___l_i_s_t_._c_p_p_:_5_3_9 |it would be nice if there was a way to iterate over these torrent_peer objects in the order they are allocated in the pool instead. | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_I_t_ _w_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee iiff tthheerree wwaass aa wwaayy ttoo iitteerraattee oovveerr tthheessee ttoorrrreenntt__ppeeeerr oobbjjeeccttss iinn tthhee oorrddeerr tthheeyy aarree aallllooccaatteedd iinn tthhee ppooooll iinnsstteeaadd.. IItt wwoouulldd pprroobbaabbllyy bbee mmoorree eeffffiicciieenntt | │ │ │ │ │ +|********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeeeerr__lliisstt..ccpppp::553399 ****** | │ │ │ │ │ +|, int session_time, torrent_state* state) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| | │ │ │ │ │ +| const int candidate_count = 10; | │ │ │ │ │ +| peers.reserve(candidate_count); | │ │ │ │ │ +| | │ │ │ │ │ +| int erase_candidate = -1; | │ │ │ │ │ +| | │ │ │ │ │ +| if (bool(m_finished) != state->is_finished) | │ │ │ │ │ +| recalculate_connect_candidates(state); | │ │ │ │ │ +| | │ │ │ │ │ +| external_ip const& external = state->ip; | │ │ │ │ │ +| int external_port = state->port; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_round_robin >= int(m_peers.size())) m_round_robin = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| int max_peerlist_size = state->max_peerlist_size; | │ │ │ │ │ +| | │ │ │ │ │ +|for (int iterations = std::min(int(m_peers.size()), 300); | │ │ │ │ │ +|iterations > 0; --iterations) | │ │ │ │ │ +| { | │ │ │ │ │ +| ++state->loop_counter; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_round_robin >= int(m_peers.size())) m_round_robin = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| torrent_peer& pe = *m_peers[m_round_robin]; | │ │ │ │ │ +| TORRENT_ASSERT(pe.in_use); | │ │ │ │ │ +| int current = m_round_robin; | │ │ │ │ │ +| | │ │ │ │ │ +| // if the number of peers is growing large | │ │ │ │ │ +| // we need to start weeding. | │ │ │ │ │ +| | │ │ │ │ │ +| if (int(m_peers.size()) >= max_peerlist_size * 0.95 | │ │ │ │ │ +| && max_peerlist_size > 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (is_erase_candidate(pe) | │ │ │ │ │ +| && (erase_candidate == -1 | │ │ │ │ │ +| || !compare_peer_erase(*m_peers[erase_candidate], pe))) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (should_erase_immediately(pe)) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (erase_candidate > current) --erase_candidate; | │ │ │ │ │ +| erase_peer(m_peers.begin() + current, state); | │ │ │ │ │ +| continue; | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| erase_candidate = current; | │ │ │ │ │ +|_ _ _ _ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_u_p_n_p_._c_p_p_:_1_0_6_ _ _ _ _ _ _ _ _ _ _ _|_u_s_e_ _b_o_o_s_t_:_:_a_s_i_o_:_:_i_p_:_:_n_e_t_w_o_r_k_ _i_n_s_t_e_a_d_ _o_f_ _n_e_t_m_a_s_k_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee bboooosstt::::aassiioo::::iipp::::nneettwwoorrkk iinnsstteeaadd ooff nneettmmaasskk ********** | │ │ │ │ │ +|****** ....//ssrrcc//uuppnnpp..ccpppp::110066 ****** | │ │ │ │ │ +|static error_code ignore_error; | │ │ │ │ │ +| | │ │ │ │ │ +|upnp::rootdevice::rootdevice() = default; | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +|upnp::rootdevice::~rootdevice() | │ │ │ │ │ |{ | │ │ │ │ │ -| TORRENT_ASSERT(str <= end); | │ │ │ │ │ +| TORRENT_ASSERT(magic == 1337); | │ │ │ │ │ +| magic = 0; | │ │ │ │ │ +|} | │ │ │ │ │ +|#else | │ │ │ │ │ +|upnp::rootdevice::~rootdevice() = default; | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| std::string ret; | │ │ │ │ │ -| while (str != end && *str != delim) | │ │ │ │ │ +|upnp::rootdevice::rootdevice(rootdevice const&) = default; | │ │ │ │ │ +|upnp::rootdevice& upnp::rootdevice::operator=(rootdevice const&) & = default; | │ │ │ │ │ +|upnp::rootdevice::rootdevice(rootdevice&&) noexcept = default; | │ │ │ │ │ +|upnp::rootdevice& upnp::rootdevice::operator=(rootdevice&&) & = default; | │ │ │ │ │ +| | │ │ │ │ │ +|upnp::upnp(io_context& ios | │ │ │ │ │ +|, aux::session_settings const& settings | │ │ │ │ │ +| , aux::portmap_callback& cb | │ │ │ │ │ +| , address_v4 const listen_address | │ │ │ │ │ +| , address_v4 const netmask | │ │ │ │ │ +| , std::string listen_device | │ │ │ │ │ +| , listen_socket_handle ls) | │ │ │ │ │ +| : m_settings(settings) | │ │ │ │ │ +| , m_callback(cb) | │ │ │ │ │ +| , m_io_service(ios) | │ │ │ │ │ +| , m_resolver(ios) | │ │ │ │ │ +| , m_multicast(ios) | │ │ │ │ │ +| , m_unicast(ios) | │ │ │ │ │ +| , m_broadcast_timer(ios) | │ │ │ │ │ +| , m_refresh_timer(ios) | │ │ │ │ │ +| , m_map_timer(ios) | │ │ │ │ │ +| , m_listen_address(listen_address) | │ │ │ │ │ +| , m_netmask(netmask) | │ │ │ │ │ +| , m_device(std::move(listen_device)) | │ │ │ │ │ +|#if TORRENT_USE_SSL | │ │ │ │ │ +| , m_ssl_ctx(ssl::context::sslv23_client) | │ │ │ │ │ +|#endif | │ │ │ │ │ +| , m_listen_handle(std::move(ls)) | │ │ │ │ │ +|{ | │ │ │ │ │ +|#if TORRENT_USE_SSL | │ │ │ │ │ +| m_ssl_ctx.set_verify_mode(ssl::context::verify_none); | │ │ │ │ │ +|#endif | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|void upnp::start() | │ │ │ │ │ +|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_p_a_t_h_._c_p_p_:_4_2_9_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t_ _t_h_i_s_ _o_n_ _a_ _F_A_T_ _v_o_l_u_m_e_ _t_o_ _s_e_e_ _w_h_a_t_ _e_r_r_o_r_ _w_e_ _g_e_t_!_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt tthhiiss oonn aa FFAATT vvoolluummee ttoo sseeee wwhhaatt eerrrroorr wwee ggeett!! ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppaatthh..ccpppp::442299 ****** | │ │ │ │ │ +|// it's possible CreateHardLink will copy the file internally too, | │ │ │ │ │ +| // if the filesystem does not support it. | │ │ │ │ │ +| ec.assign(GetLastError(), system_category()); | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // fall back to making a copy | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#else | │ │ │ │ │ +| // assume posix's link() function exists | │ │ │ │ │ +| int ret = ::link(n_exist.c_str(), n_link.c_str()); | │ │ │ │ │ +| | │ │ │ │ │ +| if (ret == 0) | │ │ │ │ │ | { | │ │ │ │ │ -| ret += *str; | │ │ │ │ │ -| ++str; | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| return; | │ │ │ │ │ | } | │ │ │ │ │ -| // skip the delimiter as well | │ │ │ │ │ -| while (str != end && *str == delim) ++str; | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| std::string maybe_url_encode(std::string const& url) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::string protocol, host, auth, path; | │ │ │ │ │ -| int port; | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| std::tie(protocol, auth, host, port, path) = parse_url_components(url, ec); | │ │ │ │ │ -| if (ec) return url; | │ │ │ │ │ +| // most errors are passed through, except for the ones that indicate that | │ │ │ │ │ +| // hard links are not supported and require a copy. | │ │ │ │ │ +|if (errno != EMLINK | │ │ │ │ │ +|&& errno != EXDEV | │ │ │ │ │ +|#ifdef TORRENT_BEOS | │ │ │ │ │ +| // haiku returns EPERM when the filesystem doesn't support hard link | │ │ │ │ │ +| && errno != EPERM | │ │ │ │ │ +|#endif | │ │ │ │ │ +| ) | │ │ │ │ │ +| { | │ │ │ │ │ +| // some error happened, report up to the caller | │ │ │ │ │ +| ec.assign(errno, system_category()); | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // first figure out if this url contains unencoded characters | │ │ │ │ │ -| if (!need_encoding(path.c_str(), int(path.size()))) | │ │ │ │ │ -| return url; | │ │ │ │ │ +| // fall back to making a copy | │ │ │ │ │ | | │ │ │ │ │ -| std::string msg; | │ │ │ │ │ -| std::string escaped_path { escape_path(path) }; | │ │ │ │ │ -| // reserve enough space so further append will | │ │ │ │ │ -|_ _ _/_/_ _o_n_l_y_ _c_o_p_y_ _v_a_l_u_e_s_ _t_o_ _e_x_i_s_t_i_n_g_ _l_o_c_a_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // if we get here, we should copy the file | │ │ │ │ │ +| storage_error se; | │ │ │ │ │ +| aux::copy_file(file, link, se); | │ │ │ │ │ +| ec = se.ec; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| bool is_directory(std::string const& f, error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| error_code e; | │ │ │ │ │ +| file_status s; | │ │ │ │ │ +| stat_file(f, &s, e); | │ │ │ │ │ +| if (!e && s.mode & file_status::directory) return true; | │ │ │ │ │ +|_ _ _e_c_ _=_ _e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 2|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |this should probably be based on time instead of number of request messages. For a very high throughput connection, 300 may be a | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_2_5_6_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_l_e_g_i_t_i_m_a_t_e_ _n_u_m_b_e_r_ _o_f_ _r_e_q_u_e_s_t_s_ _t_o_ _h_a_v_e_ _i_n_ _f_l_i_g_h_t_ _w_h_e_n_ _g_e_t_t_i_n_g_ _c_h_o_k_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tthhiiss sshhoouulldd pprroobbaabbllyy bbee bbaasseedd oonn ttiimmee iinnsstteeaadd ooff nnuummbbeerr ooff rreeqquueesstt mmeessssaaggeess.. FFoorr aa vveerryy hhiigghh tthhrroouugghhppuutt ccoonnnneeccttiioonn,, 330000 mmaayy bbee aa lleeggiittiimmaattee nnuummbbeerr ooff rreeqquueessttss ttoo hhaavvee iinn| │ │ │ │ │ |fflliigghhtt wwhheenn ggeettttiinngg cchhookkeedd ********** | │ │ │ │ │ |****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::22556622 ****** | │ │ │ │ │ |} | │ │ │ │ │ |#endif | │ │ │ │ │ @@ -3323,14 +3178,177 @@ │ │ │ │ │ |#endif | │ │ │ │ │ | disconnect(errors::timed_out_no_handshake, operation_t::bittorrent); | │ │ │ │ │ | return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ | // disconnect peers that we unchoked, but they didn't send a request in | │ │ │ │ │ |_ _ _/_/_ _t_h_e_ _l_a_s_t_ _6_0_ _s_e_c_o_n_d_s_,_ _a_n_d_ _w_e_ _h_a_v_e_n_'_t_ _b_e_e_n_ _w_o_r_k_i_n_g_ _o_n_ _s_e_r_v_i_c_i_n_g_ _a_ _r_e_q_u_e_s_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_b_d_e_c_o_d_e_._c_p_p_:_8_2_6_ _ _ _ _ _ _ _ _|_a_t_t_e_m_p_t_ _t_o_ _s_i_m_p_l_i_f_y_ _t_h_i_s_ _i_m_p_l_e_m_e_n_t_a_t_i_o_n_ _b_y_ _e_m_b_r_a_c_i_n_g_ _t_h_e_ _s_p_a_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aatttteemmpptt ttoo ssiimmpplliiffyy tthhiiss iimmpplleemmeennttaattiioonn bbyy eemmbbrraacciinngg tthhee ssppaann ********** | │ │ │ │ │ +|****** ....//ssrrcc//bbddeeccooddee..ccpppp::882266 ****** | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| bdecode_node bdecode(span buffer | │ │ │ │ │ +| , error_code& ec, int* error_pos, int depth_limit, int token_limit) | │ │ │ │ │ +| { | │ │ │ │ │ +| bdecode_node ret; | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (buffer.size() > bdecode_token::max_offset) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (error_pos) *error_pos = 0; | │ │ │ │ │ +| ec = bdecode_errors::limit_exceeded; | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // this is the stack of bdecode_token indices, into m_tokens. | │ │ │ │ │ +| // sp is the stack pointer, as index into the array, stack | │ │ │ │ │ +| int sp = 0; | │ │ │ │ │ +| TORRENT_ALLOCA(stack, stack_frame, depth_limit); | │ │ │ │ │ +| | │ │ │ │ │ +|char const* start = buffer.data(); | │ │ │ │ │ +|char const* end = start + buffer.size(); | │ │ │ │ │ +| char const* const orig_start = start; | │ │ │ │ │ +| | │ │ │ │ │ +| if (start == end) | │ │ │ │ │ +| TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); | │ │ │ │ │ +| | │ │ │ │ │ +| while (start <= end) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (start >= end) TORRENT_FAIL_BDECODE(bdecode_errors::unexpected_eof); | │ │ │ │ │ +| | │ │ │ │ │ +| if (sp >= depth_limit) | │ │ │ │ │ +| TORRENT_FAIL_BDECODE(bdecode_errors::depth_exceeded); | │ │ │ │ │ +| | │ │ │ │ │ +| --token_limit; | │ │ │ │ │ +| if (token_limit < 0) | │ │ │ │ │ +| TORRENT_FAIL_BDECODE(bdecode_errors::limit_exceeded); | │ │ │ │ │ +| | │ │ │ │ │ +| // look for a new token | │ │ │ │ │ +| char const t = *start; | │ │ │ │ │ +| | │ │ │ │ │ +| int const current_frame = sp; | │ │ │ │ │ +| | │ │ │ │ │ +| // if we're currently parsing a dictionary, assert that | │ │ │ │ │ +| // every other node is a string. | │ │ │ │ │ +| if (current_frame > 0 | │ │ │ │ │ +| && ret.m_tokens[stack[current_frame - 1].token].type == bdecode_token::dict) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (stack[current_frame - 1].state == 0) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _ _ _/_/_ _t_h_e_ _c_u_r_r_e_n_t_ _p_a_r_e_n_t_ _i_s_ _a_ _d_i_c_t_ _a_n_d_ _w_e_ _a_r_e_ _p_a_r_s_i_n_g_ _a_ _k_e_y_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/ |support authentication here. tracker_req().auth | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_u_d_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_8_1_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssuuppppoorrtt aauutthheennttiiccaattiioonn hheerree.. ttrraacckkeerr__rreeqq(())..aauutthh ********** | │ │ │ │ │ +|****** ....//ssrrcc//uuddpp__ttrraacckkeerr__ccoonnnneeccttiioonn..ccpppp::8811 ****** | │ │ │ │ │ +|udp_tracker_connection::m_connection_cache; | │ │ │ │ │ +| | │ │ │ │ │ +| std::mutex udp_tracker_connection::m_cache_mutex; | │ │ │ │ │ +| | │ │ │ │ │ +| udp_tracker_connection::udp_tracker_connection( | │ │ │ │ │ +| io_context& ios | │ │ │ │ │ +| , tracker_manager& man | │ │ │ │ │ +| , tracker_request const& req | │ │ │ │ │ +| , std::weak_ptr c) | │ │ │ │ │ +| : tracker_connection(man, req, ios, std::move(c)) | │ │ │ │ │ +| , m_transaction_id(0) | │ │ │ │ │ +| , m_attempts(0) | │ │ │ │ │ +| , m_state(action_t::error) | │ │ │ │ │ +| , m_abort(false) | │ │ │ │ │ +| { | │ │ │ │ │ +| update_transaction_id(); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void udp_tracker_connection::start() | │ │ │ │ │ +| { | │ │ │ │ │ +|std::string hostname; | │ │ │ │ │ +|std::string protocol; | │ │ │ │ │ +| int port; | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| | │ │ │ │ │ +| std::tie(protocol, std::ignore, hostname, port, std::ignore) | │ │ │ │ │ +| = parse_url_components(tracker_req().url, ec); | │ │ │ │ │ +| if (port == -1) port = protocol == "http" ? 80 : 443; | │ │ │ │ │ +| | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| tracker_connection::fail(ec, operation_t::parse_address); | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| aux::session_settings const& settings = m_man.settings(); | │ │ │ │ │ +| | │ │ │ │ │ +| int const proxy_type = settings.get_int(settings_pack::proxy_type); | │ │ │ │ │ +| | │ │ │ │ │ +| if (settings.get_bool(settings_pack::proxy_hostnames) | │ │ │ │ │ +| && (proxy_type == settings_pack::socks5 | │ │ │ │ │ +| || proxy_type == settings_pack::socks5_pw)) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_hostname = hostname; | │ │ │ │ │ +| m_target.port(std::uint16_t(port)); | │ │ │ │ │ +| start_announce(); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| using namespace std::placeholders; | │ │ │ │ │ +|_ _ _ _A_D_D___O_U_T_S_T_A_N_D_I_N_G___A_S_Y_N_C_(_"_u_d_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_:_:_n_a_m_e___l_o_o_k_u_p_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_a_l_e_r_t___m_a_n_a_g_e_r_._c_p_p_:_8_0_ _ _ _|_k_e_e_p_ _a_ _c_o_u_n_t_ _o_f_ _t_h_e_ _n_u_m_b_e_r_ _o_f_ _t_h_r_e_a_d_s_ _w_a_i_t_i_n_g_._ _O_n_l_y_ _i_f_ _i_t_'_s_ _>_ _0_ _n_o_t_i_f_y_ _t_h_e_m_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** kkeeeepp aa ccoouunntt ooff tthhee nnuummbbeerr ooff tthhrreeaaddss wwaaiittiinngg.. OOnnllyy iiff iitt''ss >> 00 nnoottiiffyy tthheemm ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt__mmaannaaggeerr..ccpppp::8800 ****** | │ │ │ │ │ +|return m_alerts[m_generation].front(); | │ │ │ │ │ +| | │ │ │ │ │ +| // this call can be interrupted prematurely by other signals | │ │ │ │ │ +| m_condition.wait_for(lock, max_wait); | │ │ │ │ │ +| if (!m_alerts[m_generation].empty()) | │ │ │ │ │ +| return m_alerts[m_generation].front(); | │ │ │ │ │ +| | │ │ │ │ │ +| return nullptr; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void alert_manager::maybe_notify(alert* a) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_alerts[m_generation].size() == 1) | │ │ │ │ │ +| { | │ │ │ │ │ +| // we just posted to an empty queue. If anyone is waiting for | │ │ │ │ │ +| // alerts, we need to notify them. Also (potentially) call the | │ │ │ │ │ +| // user supplied m_notify callback to let the client wake up its | │ │ │ │ │ +| // message loop to poll for alerts. | │ │ │ │ │ +| if (m_notify) m_notify(); | │ │ │ │ │ +| | │ │ │ │ │ +|m_condition.notify_all(); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ +| for (auto& e : m_ses_extensions) | │ │ │ │ │ +| e->on_alert(a); | │ │ │ │ │ +|#else | │ │ │ │ │ +| TORRENT_UNUSED(a); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void alert_manager::set_notify_function(std::function const& fun) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::unique_lock lock(m_mutex); | │ │ │ │ │ +| m_notify = fun; | │ │ │ │ │ +| if (!m_alerts[m_generation].empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_notify) m_notify(); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ +| void alert_manager::add_extension(std::shared_ptr ext) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_ses_extensions.push_back(std::move(ext)); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| void alert_manager::get_all(std::vector& alerts) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _s_t_d_:_:_l_o_c_k___g_u_a_r_d_<_s_t_d_:_:_r_e_c_u_r_s_i_v_e___m_u_t_e_x_>_ _l_o_c_k_(_m___m_u_t_e_x_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_r_a_c_k_e_r___m_a_n_a_g_e_r_._c_p_p_:_3_6_9_|_i_m_p_l_e_m_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** iimmpplleemmeenntt ********** | │ │ │ │ │ |****** ....//ssrrcc//ttrraacckkeerr__mmaannaaggeerr..ccpppp::336699 ****** | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ | if (m_ses.should_log()) | │ │ │ │ │ | { | │ │ │ │ │ | m_ses.session_log("incoming UDP tracker packet from %s has invalid " | │ │ │ │ │ @@ -3540,284 +3558,68 @@ │ │ │ │ │ | TORRENT_ASSERT(info.num_peers == 0); | │ │ │ │ │ | | │ │ │ │ │ | TORRENT_ASSERT(i->writing > 0); | │ │ │ │ │ | TORRENT_ASSERT(info.state == block_info::state_writing); | │ │ │ │ │ | | │ │ │ │ │ | if (info.state == block_info::state_finished) return; | │ │ │ │ │ |_ _ _i_f_ _(_i_n_f_o_._s_t_a_t_e_ _=_=_ _b_l_o_c_k___i_n_f_o_:_:_s_t_a_t_e___w_r_i_t_i_n_g_)_ _-_-_i_-_>_w_r_i_t_i_n_g_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_5_0_4_ _ _ _ _ _ _ _ _|_p_o_s_t_ _a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ppoosstt aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::550044 ****** | │ │ │ │ │ -|if (m_current_gauge_state != no_gauge_state) | │ │ │ │ │ -| inc_stats_counter(m_current_gauge_state + counters::num_checking_torrents, -1); | │ │ │ │ │ -| if (new_gauge_state != no_gauge_state) | │ │ │ │ │ -| inc_stats_counter(new_gauge_state + counters::num_checking_torrents, 1); | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(new_gauge_state >= 0); | │ │ │ │ │ -| TORRENT_ASSERT(new_gauge_state <= no_gauge_state); | │ │ │ │ │ -| m_current_gauge_state = static_cast(new_gauge_state); | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_e_s_c_a_p_e___s_t_r_i_n_g_._c_p_p_:_1_9_4_ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _m_o_v_e_d_ _i_n_t_o_ _s_t_r_i_n_g___u_t_i_l_._c_p_p_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd pprroobbaabbllyy bbee mmoovveedd iinnttoo ssttrriinngg__uuttiill..ccpppp ********** | │ │ │ │ │ +|****** ....//ssrrcc//eessccaappee__ssttrriinngg..ccpppp::119944 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| return escape_string_impl(str.data(), int(str.size()), 10); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::leave_seed_mode(seed_mode_t const checking) | │ │ │ │ │ +| bool need_encoding(char const* str, int const len) | │ │ │ │ │ | { | │ │ │ │ │ -| if (!m_seed_mode) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (checking == seed_mode_t::check_files) | │ │ │ │ │ -| { | │ │ │ │ │ -| // this means the user promised we had all the | │ │ │ │ │ -| // files, but it turned out we didn't. This is | │ │ │ │ │ -| // an error. | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| debug_log("*** FAILED SEED MODE, rechecking"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| debug_log("*** LEAVING SEED MODE (%s)" | │ │ │ │ │ -| , checking == seed_mode_t::skip_checking ? "as seed" : "as non-seed"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| m_seed_mode = false; | │ │ │ │ │ -| // seed is false if we turned out not | │ │ │ │ │ -| // to be a seed after all | │ │ │ │ │ -| if (checking == seed_mode_t::check_files | │ │ │ │ │ -| && state() != torrent_status::checking_resume_data) | │ │ │ │ │ +| for (int i = 0; i < len; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| m_have_all = false; | │ │ │ │ │ -| set_state(torrent_status::downloading); | │ │ │ │ │ -| force_recheck(); | │ │ │ │ │ +| if (std::strchr(unreserved_chars, *str) == nullptr || *str == 0) | │ │ │ │ │ +| return true; | │ │ │ │ │ +| ++str; | │ │ │ │ │ | } | │ │ │ │ │ -| m_num_verified = 0; | │ │ │ │ │ -| m_verified.clear(); | │ │ │ │ │ -| m_verifying.clear(); | │ │ │ │ │ -| | │ │ │ │ │ -| set_need_save_resume(torrent_handle::if_state_changed); | │ │ │ │ │ +| return false; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::verified(piece_index_t const piece) | │ │ │ │ │ +| void convert_path_to_posix(std::string& path) | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(!m_verified.get_bit(piece)); | │ │ │ │ │ -|_ _ _+_+_m___n_u_m___v_e_r_i_f_i_e_d_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_8_5_2_ _ _ _ _ _ _ _|_a_d_d_ _a_ _u_n_i_t_ _t_e_s_t_ _w_h_e_r_e_ _w_e_ _d_o_n_'_t_ _h_a_v_e_ _m_e_t_a_d_a_t_a_,_ _c_o_n_n_e_c_t_ _t_o_ _a_ _p_e_e_r_ _t_h_a_t_ _s_e_n_d_s_ _a_ _b_i_t_f_i_e_l_d_ _t_h_a_t_'_s_ _t_o_o_ _l_a_r_g_e_,_ _t_h_e_n_ _w_e_ _g_e_t_ _t_h_e_ _m_e_t_a_d_a_t_a_ _ _ _ | │ │ │ │ │ -|********** aadddd aa uunniitt tteesstt wwhheerree wwee ddoonn''tt hhaavvee mmeettaaddaattaa,, ccoonnnneecctt ttoo aa ppeeeerr tthhaatt sseennddss aa bbiittffiieelldd tthhaatt''ss ttoooo llaarrggee,, tthheenn wwee ggeett tthhee mmeettaaddaattaa ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11885522 ****** | │ │ │ │ │ -|for (auto const& f : m_add_torrent_params->renamed_files) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (f.first < file_index_t(0) || f.first >= fs.end_file()) continue; | │ │ │ │ │ -| m_torrent_file->rename_file(file_index_t(f.first), f.second); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| construct_storage(); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_SHARE_MODE | │ │ │ │ │ -| if (m_share_mode && valid_metadata()) | │ │ │ │ │ -| { | │ │ │ │ │ -| // in share mode, all pieces have their priorities initialized to 0 | │ │ │ │ │ -| m_file_priority.clear(); | │ │ │ │ │ -| m_file_priority.resize(m_torrent_file->num_files(), dont_download); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| // it's important to initialize the peers early, because this is what will | │ │ │ │ │ -| // fix up their have-bitmasks to have the correct size | │ │ │ │ │ -|if (!m_connections_initialized) | │ │ │ │ │ -|{ | │ │ │ │ │ -| m_connections_initialized = true; | │ │ │ │ │ -| // all peer connections have to initialize themselves now that the metadata | │ │ │ │ │ -| // is available | │ │ │ │ │ -| // copy the peer list since peers may disconnect and invalidate | │ │ │ │ │ -| // m_connections as we initialize them | │ │ │ │ │ -| for (auto c : m_connections) | │ │ │ │ │ -| { | │ │ │ │ │ -| auto pc = c->self(); | │ │ │ │ │ -| if (pc->is_disconnecting()) continue; | │ │ │ │ │ -| pc->on_metadata_impl(); | │ │ │ │ │ -| if (pc->is_disconnecting()) continue; | │ │ │ │ │ -| pc->init(); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // in case file priorities were passed in via the add_torrent_params | │ │ │ │ │ -| // and also in the case of share mode, we need to update the priorities | │ │ │ │ │ -| // this has to be applied before piece priority | │ │ │ │ │ -| if (!m_file_priority.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| // m_file_priority was loaded from the resume data, this doesn't | │ │ │ │ │ -| // alter any state that needs to be saved in the resume data | │ │ │ │ │ -| auto const ns = m_need_save_resume_data; | │ │ │ │ │ -| update_piece_priorities(m_file_priority); | │ │ │ │ │ -| m_need_save_resume_data = ns; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_add_torrent_params) | │ │ │ │ │ -|_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_4_9_2_ _ _ _ _ _ _ _|_u_s_e_ _c_h_r_o_n_o_ _t_y_p_e_ _f_o_r_ _t_i_m_e_ _d_u_r_a_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee cchhrroonnoo ttyyppee ffoorr ttiimmee dduurraattiioonn ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44449922 ****** | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| m_picker->piece_passed(index); | │ │ │ │ │ -| update_gauge(); | │ │ │ │ │ -| we_have(index); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| debug_log("we_have(%d) (num_have: %d)", int(index), num_have()); | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_STREAMING | │ │ │ │ │ -| remove_time_critical_piece(index, true); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| std::replace(path.begin(), path.end(), '\\', '/'); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_PREDICTIVE_PIECES | │ │ │ │ │ -| // we believe we will complete this piece very soon | │ │ │ │ │ -| // announce it to peers ahead of time to eliminate the | │ │ │ │ │ -| // round-trip times involved in announcing it, requesting it | │ │ │ │ │ -| // and sending it | │ │ │ │ │ -|void torrent::predicted_have_piece(piece_index_t const index, int const milliseconds) | │ │ │ │ │ +|std::string read_until(char const*& str, char const delim, char const* end) | │ │ │ │ │ |{ | │ │ │ │ │ -| auto const i = std::lower_bound(m_predictive_pieces.begin() | │ │ │ │ │ -| , m_predictive_pieces.end(), index); | │ │ │ │ │ -| if (i != m_predictive_pieces.end() && *i == index) return; | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto p : m_connections) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_INCREMENT(m_iterating_connections); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| p->peer_log(peer_log_alert::outgoing, "PREDICTIVE_HAVE", "piece: %d expected in %d ms" | │ │ │ │ │ -| , static_cast(index), milliseconds); | │ │ │ │ │ -|#else | │ │ │ │ │ -| TORRENT_UNUSED(milliseconds); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| p->announce_piece(index); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| m_predictive_pieces.insert(i, index); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| // blocks may contain the block indices of the blocks that failed (if this is | │ │ │ │ │ -| // a v2 torrent). | │ │ │ │ │ -| void torrent::piece_failed(piece_index_t const index, std::vector blocks) | │ │ │ │ │ -| { | │ │ │ │ │ -| // if the last piece fails the peer connection will still | │ │ │ │ │ -| // think that it has received all of it until this function | │ │ │ │ │ -| // resets the download queue. So, we cannot do the | │ │ │ │ │ -| // invariant check here since it assumes: | │ │ │ │ │ -|_ _ _/_/_ _(_t_o_t_a_l___d_o_n_e_ _=_=_ _m___t_o_r_r_e_n_t___f_i_l_e_-_>_t_o_t_a_l___s_i_z_e_(_)_)_ _=_>_ _i_s___s_e_e_d_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_9_1_9_ _ _ _ _ _ _ _|_a_b_o_r_t_ _l_o_o_k_u_p_s_ _t_h_i_s_ _t_o_r_r_e_n_t_ _h_a_s_ _m_a_d_e_ _v_i_a_ _t_h_e_ _s_e_s_s_i_o_n_ _h_o_s_t_ _r_e_s_o_l_v_e_r_ _i_n_t_e_r_f_a_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aabboorrtt llooookkuuppss tthhiiss ttoorrrreenntt hhaass mmaaddee vviiaa tthhee sseessssiioonn hhoosstt rreessoollvveerr iinntteerrffaaccee ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44991199 ****** | │ │ │ │ │ -|TORRENT_UNUSED(e); | │ │ │ │ │ -| m_storage.reset(); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| debug_log("Failed to flush disk cache: %s", e.what()); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| // clients may rely on this alert to be posted, so it's probably a | │ │ │ │ │ -| // good idea to post it here, even though we failed | │ │ │ │ │ -| if (alerts().should_post()) | │ │ │ │ │ -| alerts().emplace_alert(get_handle()); | │ │ │ │ │ -| } | │ │ │ │ │ -| m_ses.deferred_submit_jobs(); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| if (alerts().should_post()) | │ │ │ │ │ -| alerts().emplace_alert(get_handle()); | │ │ │ │ │ -| alerts().emplace_alert(get_handle() | │ │ │ │ │ -| , info_hash(), get_userdata()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|if (!m_apply_ip_filter) | │ │ │ │ │ -| { | │ │ │ │ │ -| inc_stats_counter(counters::non_filter_torrents, -1); | │ │ │ │ │ -| m_apply_ip_filter = true; | │ │ │ │ │ -| } | │ │ │ │ │ +| TORRENT_ASSERT(str <= end); | │ │ │ │ │ | | │ │ │ │ │ -| m_paused = false; | │ │ │ │ │ -| m_auto_managed = false; | │ │ │ │ │ -| update_state_list(); | │ │ │ │ │ -| for (torrent_list_index_t i{}; i != m_links.end_index(); ++i) | │ │ │ │ │ +| std::string ret; | │ │ │ │ │ +| while (str != end && *str != delim) | │ │ │ │ │ | { | │ │ │ │ │ -| if (!m_links[i].in_list()) continue; | │ │ │ │ │ -| m_links[i].unlink(m_ses.torrent_list(i), i); | │ │ │ │ │ +| ret += *str; | │ │ │ │ │ +| ++str; | │ │ │ │ │ | } | │ │ │ │ │ -| // don't re-add this torrent to the state-update list | │ │ │ │ │ -| m_state_subscription = false; | │ │ │ │ │ +| // skip the delimiter as well | │ │ │ │ │ +| while (str != end && *str == delim) ++str; | │ │ │ │ │ +| return ret; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // this is called when we're destructing non-gracefully. i.e. we're _just_ | │ │ │ │ │ -| // destructing everything. | │ │ │ │ │ -| void torrent::panic() | │ │ │ │ │ +| std::string maybe_url_encode(std::string const& url) | │ │ │ │ │ | { | │ │ │ │ │ -| m_storage.reset(); | │ │ │ │ │ -| // if there are any other peers allocated still, we need to clear them | │ │ │ │ │ -| // now. They can't be cleared later because the allocator will already | │ │ │ │ │ -| // have been destructed | │ │ │ │ │ -| if (m_peer_list) m_peer_list->clear(); | │ │ │ │ │ -| m_connections.clear(); | │ │ │ │ │ -| m_outgoing_pids.clear(); | │ │ │ │ │ -|_ _ _m___p_e_e_r_s___t_o___d_i_s_c_o_n_n_e_c_t_._c_l_e_a_r_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_8_0_3_2 |if peer is a really good peer, maybe we shouldn't disconnect it perhaps this logic should be disabled if we have too many idle peers| │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_(_w_i_t_h_ _s_o_m_e_ _d_e_f_i_n_i_t_i_o_n_ _o_f_ _i_d_l_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iiff ppeeeerr iiss aa rreeaallllyy ggoooodd ppeeeerr,, mmaayybbee wwee sshhoouullddnn''tt ddiissccoonnnneecctt iitt ppeerrhhaappss tthhiiss llooggiicc sshhoouulldd bbee ddiissaabblleedd iiff wwee hhaavvee ttoooo mmaannyy iiddllee ppeeeerrss ((wwiitthh ssoommee ddeeffiinniittiioonn ooff iiddllee)) **********| │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::88003322 ****** | │ │ │ │ │ -| m_peers_to_disconnect.reserve(m_connections.size() + 1); | │ │ │ │ │ -| m_connections.reserve(m_connections.size() + 1); | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| std::string protocol, host, auth, path; | │ │ │ │ │ +| int port; | │ │ │ │ │ | error_code ec; | │ │ │ │ │ -| TORRENT_ASSERT(p->remote() == p->get_socket().remote_endpoint(ec) || ec); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(p->peer_info_struct() != nullptr); | │ │ │ │ │ +| std::tie(protocol, auth, host, port, path) = parse_url_components(url, ec); | │ │ │ │ │ +| if (ec) return url; | │ │ │ │ │ | | │ │ │ │ │ -| // we need to do this after we've added the peer to the peer_list | │ │ │ │ │ -| // since that's when the peer is assigned its peer_info object, | │ │ │ │ │ -| // which holds the rank | │ │ │ │ │ -| if (maybe_replace_peer) | │ │ │ │ │ -| { | │ │ │ │ │ -| // now, find the lowest rank peer and disconnect that | │ │ │ │ │ -| // if it's lower rank than the incoming connection | │ │ │ │ │ -| peer_connection* peer = find_lowest_ranking_peer(); | │ │ │ │ │ +| // first figure out if this url contains unencoded characters | │ │ │ │ │ +| if (!need_encoding(path.c_str(), int(path.size()))) | │ │ │ │ │ +| return url; | │ │ │ │ │ | | │ │ │ │ │ -|if (peer != nullptr && peer->peer_rank() < p->peer_rank()) | │ │ │ │ │ -|{ | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -| debug_log("CLOSING CONNECTION \"%s\" peer list full (low peer rank) " | │ │ │ │ │ -| "connections: %d limit: %d" | │ │ │ │ │ -| , print_endpoint(peer->remote()).c_str() | │ │ │ │ │ -| , num_peers() | │ │ │ │ │ -| , m_max_connections); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| peer->disconnect(errors::too_many_connections, operation_t::bittorrent); | │ │ │ │ │ -| p->peer_disconnected_other(); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -| debug_log("CLOSING CONNECTION \"%s\" peer list full (low peer rank) " | │ │ │ │ │ -| "connections: %d limit: %d" | │ │ │ │ │ -| , print_endpoint(p->remote()).c_str() | │ │ │ │ │ -| , num_peers() | │ │ │ │ │ -| , m_max_connections); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| p->disconnect(errors::too_many_connections, operation_t::bittorrent); | │ │ │ │ │ -| // we have to do this here because from the peer's point of view | │ │ │ │ │ -| // it wasn't really attached to the torrent, but we do need | │ │ │ │ │ -|_ _ _ _ _/_/_ _t_o_ _l_e_t_ _p_e_e_r___l_i_s_t_ _k_n_o_w_ _w_e_'_r_e_ _r_e_m_o_v_i_n_g_ _i_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| std::string msg; | │ │ │ │ │ +| std::string escaped_path { escape_path(path) }; | │ │ │ │ │ +| // reserve enough space so further append will | │ │ │ │ │ +|_ _ _/_/_ _o_n_l_y_ _c_o_p_y_ _v_a_l_u_e_s_ _t_o_ _e_x_i_s_t_i_n_g_ _l_o_c_a_t_i_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ | |_._._/_s_r_c_/ | | │ │ │ │ │ |relevance 2|_h_t_t_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |returning a bool here is redundant. Instead this function should return the peer_entry | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_4_7_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** rreettuurrnniinngg aa bbooooll hheerree iiss rreedduunnddaanntt.. IInnsstteeaadd tthhiiss ffuunnccttiioonn sshhoouulldd rreettuurrnn tthhee ppeeeerr__eennttrryy ********** | │ │ │ │ │ |****** ....//ssrrcc//hhttttpp__ttrraacckkeerr__ccoonnnneeccttiioonn..ccpppp::447799 ****** | │ │ │ │ │ |{ | │ │ │ │ │ | cb->tracker_scrape_response(tracker_req(), resp.complete | │ │ │ │ │ @@ -3866,124 +3668,322 @@ │ │ │ │ │ | return false; | │ │ │ │ │ | } | │ │ │ │ │ | ret.hostname = i.string_value().to_string(); | │ │ │ │ │ | | │ │ │ │ │ | // extract port | │ │ │ │ │ | i = info.dict_find_int("port"); | │ │ │ │ │ |_ _ _i_f_ _(_!_i_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_p_a_t_h_._c_p_p_:_4_2_9_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t_ _t_h_i_s_ _o_n_ _a_ _F_A_T_ _v_o_l_u_m_e_ _t_o_ _s_e_e_ _w_h_a_t_ _e_r_r_o_r_ _w_e_ _g_e_t_!_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt tthhiiss oonn aa FFAATT vvoolluummee ttoo sseeee wwhhaatt eerrrroorr wwee ggeett!! ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppaatthh..ccpppp::442299 ****** | │ │ │ │ │ -|// it's possible CreateHardLink will copy the file internally too, | │ │ │ │ │ -| // if the filesystem does not support it. | │ │ │ │ │ -| ec.assign(GetLastError(), system_category()); | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_9_9_ _ _ _|_i_s_ _t_h_e_r_e_ _a_ _r_e_a_s_o_n_ _n_o_t_ _t_o_ _m_o_v_e_ _a_l_l_ _o_f_ _t_h_i_s_ _i_n_t_o_ _i_n_i_t_(_)_?_ _a_n_d_ _j_u_s_t_ _p_o_s_t_ _i_t_ _t_o_ _t_h_e_ _i_o___c_o_n_t_e_x_t_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iiss tthheerree aa rreeaassoonn nnoott ttoo mmoovvee aallll ooff tthhiiss iinnttoo iinniitt(())?? aanndd jjuusstt ppoosstt iitt ttoo tthhee iioo__ccoonntteexxtt?? ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::559999 ****** | │ │ │ │ │ +|try | │ │ │ │ │ +|#endif | │ │ │ │ │ +| { | │ │ │ │ │ +| (this->*f)(std::forward(a)...); | │ │ │ │ │ +| } | │ │ │ │ │ +|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ +| catch (system_error const& e) { | │ │ │ │ │ +| alerts().emplace_alert(e.code(), e.what()); | │ │ │ │ │ +| pause(); | │ │ │ │ │ +| } catch (std::exception const& e) { | │ │ │ │ │ +| alerts().emplace_alert(error_code(), e.what()); | │ │ │ │ │ +| pause(); | │ │ │ │ │ +| } catch (...) { | │ │ │ │ │ +| alerts().emplace_alert(error_code(), "unknown error"); | │ │ │ │ │ +| pause(); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| // fall back to making a copy | │ │ │ │ │ +| // This function is called by the creating thread, not in the message loop's | │ │ │ │ │ +| // io_context thread. | │ │ │ │ │ +|void session_impl::start_session() | │ │ │ │ │ +|{ | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| session_log("start session"); | │ │ │ │ │ |#endif | │ │ │ │ │ -|#else | │ │ │ │ │ -| // assume posix's link() function exists | │ │ │ │ │ -| int ret = ::link(n_exist.c_str(), n_link.c_str()); | │ │ │ │ │ | | │ │ │ │ │ -| if (ret == 0) | │ │ │ │ │ +|#if TORRENT_USE_SSL | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| m_ssl_ctx.set_default_verify_paths(ec); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (ec) session_log("SSL set_default verify_paths failed: %s", ec.message().c_str()); | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +|#endif | │ │ │ │ │ +|_#_i_f_ _d_e_f_i_n_e_d_ _T_O_R_R_E_N_T___W_I_N_D_O_W_S_ _&_&_ _d_e_f_i_n_e_d_ _T_O_R_R_E_N_T___U_S_E___O_P_E_N_S_S_L_ _&_&_ _!_d_e_f_i_n_e_d_ _T_O_R_R_E_N_T___W_I_N_R_T_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_7_6_1_ _ _ _|_t_h_e_ _i_p_ _f_i_l_t_e_r_ _s_h_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _s_a_v_e_d_ _h_e_r_e_ _t_o_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhee iipp ffiilltteerr sshhoouulldd pprroobbaabbllyy bbee ssaavveedd hheerree ttoooo ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::776611 ****** | │ │ │ │ │ +|m_lsd_announce_timer.async_wait([this](error_code const& e) { | │ │ │ │ │ +| wrap(&session_impl::on_lsd_announce, e); } ); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| session_log(" done starting session"); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // this applies unchoke settings from m_settings | │ │ │ │ │ +| recalculate_unchoke_slots(); | │ │ │ │ │ +| | │ │ │ │ │ +| // apply all m_settings to this session | │ │ │ │ │ +| run_all_updates(*this); | │ │ │ │ │ +| reopen_listen_sockets(false); | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_USE_INVARIANT_CHECKS | │ │ │ │ │ +| check_invariant(); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION <= 2 | │ │ │ │ │ +|void session_impl::save_state(entry* eptr, save_state_flags_t const flags) const | │ │ │ │ │ +|{ | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| entry& e = *eptr; | │ │ │ │ │ +| // make it a dict | │ │ │ │ │ +| e.dict(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (flags & session::save_settings) | │ │ │ │ │ | { | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -| return; | │ │ │ │ │ +| entry::dictionary_type& sett = e["settings"].dict(); | │ │ │ │ │ +| save_settings_to_dict(non_default_settings(m_settings), sett); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // most errors are passed through, except for the ones that indicate that | │ │ │ │ │ -| // hard links are not supported and require a copy. | │ │ │ │ │ -|if (errno != EMLINK | │ │ │ │ │ -|&& errno != EXDEV | │ │ │ │ │ -|#ifdef TORRENT_BEOS | │ │ │ │ │ -| // haiku returns EPERM when the filesystem doesn't support hard link | │ │ │ │ │ -| && errno != EPERM | │ │ │ │ │ -|#endif | │ │ │ │ │ -| ) | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| if (flags & session::save_dht_settings) | │ │ │ │ │ | { | │ │ │ │ │ -| // some error happened, report up to the caller | │ │ │ │ │ -| ec.assign(errno, system_category()); | │ │ │ │ │ -| return; | │ │ │ │ │ +| e["dht"] = dht::save_dht_settings(get_dht_settings()); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // fall back to making a copy | │ │ │ │ │ +| if (m_dht && (flags & session::save_dht_state)) | │ │ │ │ │ +| { | │ │ │ │ │ +| e["dht state"] = dht::save_dht_state(m_dht->state()); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ +| for (auto const& ext : m_ses_extensions[plugins_all_idx]) | │ │ │ │ │ +| { | │ │ │ │ │ +| ext->save_state(*eptr); | │ │ │ │ │ +|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_3_8_8_2 |make a list for torrents that want to be announced on the DHT so we don't have to loop over all torrents, just to find the ones that| │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_w_a_n_t_ _t_o_ _a_n_n_o_u_n_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmaakkee aa lliisstt ffoorr ttoorrrreennttss tthhaatt wwaanntt ttoo bbee aannnnoouunncceedd oonn tthhee DDHHTT ssoo wwee ddoonn''tt hhaavvee ttoo lloooopp oovveerr aallll ttoorrrreennttss,, jjuusstt ttoo ffiinndd tthhee oonneess tthhaatt wwaanntt ttoo aannnnoouunnccee ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::33888822 ****** | │ │ │ │ │ +|if (!m_dht_torrents.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::shared_ptr t; | │ │ │ │ │ +| do | │ │ │ │ │ +| { | │ │ │ │ │ +| t = m_dht_torrents.front().lock(); | │ │ │ │ │ +| m_dht_torrents.pop_front(); | │ │ │ │ │ +| } while (!t && !m_dht_torrents.empty()); | │ │ │ │ │ +| | │ │ │ │ │ +| if (t) | │ │ │ │ │ +| { | │ │ │ │ │ +| t->dht_announce(); | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| if (m_torrents.empty()) return; | │ │ │ │ │ | | │ │ │ │ │ +| if (m_next_dht_torrent >= m_torrents.size()) | │ │ │ │ │ +| m_next_dht_torrent = 0; | │ │ │ │ │ +| m_torrents[m_next_dht_torrent]->dht_announce(); | │ │ │ │ │ +|++m_next_dht_torrent; | │ │ │ │ │ +|if (m_next_dht_torrent >= m_torrents.size()) | │ │ │ │ │ +| m_next_dht_torrent = 0; | │ │ │ │ │ +| } | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| // if we get here, we should copy the file | │ │ │ │ │ -| storage_error se; | │ │ │ │ │ -| aux::copy_file(file, link, se); | │ │ │ │ │ -| ec = se.ec; | │ │ │ │ │ +| void session_impl::on_lsd_announce(error_code const& e) | │ │ │ │ │ +| { | │ │ │ │ │ +| COMPLETE_ASYNC("session_impl::on_lsd_announce"); | │ │ │ │ │ +| m_stats_counters.inc_stats_counter(counters::on_lsd_counter); | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| if (e) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_abort) return; | │ │ │ │ │ +| | │ │ │ │ │ +| ADD_OUTSTANDING_ASYNC("session_impl::on_lsd_announce"); | │ │ │ │ │ +| // announce on local network every 5 minutes | │ │ │ │ │ +| int const delay = std::max(m_settings.get_int(settings_pack::local_service_announce_interval) | │ │ │ │ │ +| / std::max(int(m_torrents.size()), 1), 1); | │ │ │ │ │ +| m_lsd_announce_timer.expires_after(seconds(delay)); | │ │ │ │ │ +| m_lsd_announce_timer.async_wait([this](error_code const& err) { | │ │ │ │ │ +| wrap(&session_impl::on_lsd_announce, err); }); | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_torrents.empty()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_next_lsd_torrent >= m_torrents.size()) | │ │ │ │ │ +| m_next_lsd_torrent = 0; | │ │ │ │ │ +| m_torrents[m_next_lsd_torrent]->lsd_announce(); | │ │ │ │ │ +| ++m_next_lsd_torrent; | │ │ │ │ │ +| if (m_next_lsd_torrent >= m_torrents.size()) | │ │ │ │ │ +|_ _ _ _m___n_e_x_t___l_s_d___t_o_r_r_e_n_t_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_5_1_5_ _ _|_t_h_i_s_ _f_u_n_c_t_i_o_n_ _s_h_o_u_l_d_ _b_e_ _r_e_m_o_v_e_d_ _a_n_d_ _u_s_e_r_s_ _n_e_e_d_ _t_o_ _d_e_a_l_ _w_i_t_h_ _t_h_e_ _m_o_r_e_ _g_e_n_e_r_i_c_ _c_a_s_e_ _o_f_ _h_a_v_i_n_g_ _m_u_l_t_i_p_l_e_ _l_i_s_t_e_n_ _p_o_r_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ffuunnccttiioonn sshhoouulldd bbee rreemmoovveedd aanndd uusseerrss nneeeedd ttoo ddeeaall wwiitthh tthhee mmoorree ggeenneerriicc ccaassee ooff hhaavviinngg mmuullttiippllee lliisstteenn ppoorrttss ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55551155 ****** | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (!node_list.empty() && nodes.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| session_log("ERROR: failed to parse DHT bootstrap list: %s", node_list.c_str()); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| for (auto const& n : nodes) | │ │ │ │ │ +| add_dht_router(n); | │ │ │ │ │ +|#endif | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| bool is_directory(std::string const& f, error_code& ec) | │ │ │ │ │ +| void session_impl::update_count_slow() | │ │ │ │ │ | { | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -| error_code e; | │ │ │ │ │ -| file_status s; | │ │ │ │ │ -| stat_file(f, &s, e); | │ │ │ │ │ -| if (!e && s.mode & file_status::directory) return true; | │ │ │ │ │ -|_ _ _e_c_ _=_ _e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/_p_e_e_r___l_i_s_t_._c_p_p_:_5_3_9 |it would be nice if there was a way to iterate over these torrent_peer objects in the order they are allocated in the pool instead. | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_I_t_ _w_o_u_l_d_ _p_r_o_b_a_b_l_y_ _b_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee iiff tthheerree wwaass aa wwaayy ttoo iitteerraattee oovveerr tthheessee ttoorrrreenntt__ppeeeerr oobbjjeeccttss iinn tthhee oorrddeerr tthheeyy aarree aallllooccaatteedd iinn tthhee ppooooll iinnsstteeaadd.. IItt wwoouulldd pprroobbaabbllyy bbee mmoorree eeffffiicciieenntt | │ │ │ │ │ -|********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeeeerr__lliisstt..ccpppp::553399 ****** | │ │ │ │ │ -|, int session_time, torrent_state* state) | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| for (auto const& tp : m_torrents) | │ │ │ │ │ +| { | │ │ │ │ │ +| tp->on_inactivity_tick(ec); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|std::uint16_t session_impl::listen_port() const | │ │ │ │ │ +|{ | │ │ │ │ │ +| return listen_port(nullptr); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| std::uint16_t session_impl::listen_port(listen_socket_t* sock) const | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ +| if (m_listen_sockets.empty()) return 0; | │ │ │ │ │ +| if (sock) | │ │ │ │ │ +| { | │ │ │ │ │ +| // if we're using a proxy, we won't be able to accept any TCP | │ │ │ │ │ +| // connections. Not even uTP connections via the port we know about. | │ │ │ │ │ +| // The DHT may use the implied port to make it work, but the port we | │ │ │ │ │ +| // announce here has no relevance for that. | │ │ │ │ │ +| if (sock->flags & listen_socket_t::proxy) | │ │ │ │ │ +| return 0; | │ │ │ │ │ | | │ │ │ │ │ -| const int candidate_count = 10; | │ │ │ │ │ -| peers.reserve(candidate_count); | │ │ │ │ │ +| if (!(sock->flags & listen_socket_t::accept_incoming)) | │ │ │ │ │ +| return 0; | │ │ │ │ │ | | │ │ │ │ │ -| int erase_candidate = -1; | │ │ │ │ │ +| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (bool(m_finished) != state->is_finished) | │ │ │ │ │ -| recalculate_connect_candidates(state); | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| for (auto const& s : m_listen_sockets) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!(s->flags & listen_socket_t::accept_incoming)) continue; | │ │ │ │ │ +| if (s->ssl == transport::plaintext) | │ │ │ │ │ +| return std::uint16_t(s->tcp_external_port()); | │ │ │ │ │ +| } | │ │ │ │ │ +|_ _ _r_e_t_u_r_n_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_5_5_5_ _ _|_t_h_i_s_ _f_u_n_c_t_i_o_n_ _s_h_o_u_l_d_ _b_e_ _r_e_m_o_v_e_d_ _a_n_d_ _u_s_e_r_s_ _n_e_e_d_ _t_o_ _d_e_a_l_ _w_i_t_h_ _t_h_e_ _m_o_r_e_ _g_e_n_e_r_i_c_ _c_a_s_e_ _o_f_ _h_a_v_i_n_g_ _m_u_l_t_i_p_l_e_ _s_s_l_ _p_o_r_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ffuunnccttiioonn sshhoouulldd bbee rreemmoovveedd aanndd uusseerrss nneeeedd ttoo ddeeaall wwiitthh tthhee mmoorree ggeenneerriicc ccaassee ooff hhaavviinngg mmuullttiippllee ssssll ppoorrttss ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55555555 ****** | │ │ │ │ │ +|return 0; | │ │ │ │ │ | | │ │ │ │ │ -| external_ip const& external = state->ip; | │ │ │ │ │ -| int external_port = state->port; | │ │ │ │ │ +| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (m_round_robin >= int(m_peers.size())) m_round_robin = 0; | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| for (auto const& s : m_listen_sockets) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!(s->flags & listen_socket_t::accept_incoming)) continue; | │ │ │ │ │ +| if (s->ssl == transport::plaintext) | │ │ │ │ │ +| return std::uint16_t(s->tcp_external_port()); | │ │ │ │ │ +| } | │ │ │ │ │ +| return 0; | │ │ │ │ │ +|#else | │ │ │ │ │ +| sock = m_listen_sockets.front().get(); | │ │ │ │ │ +| if (!(sock->flags & listen_socket_t::accept_incoming)) return 0; | │ │ │ │ │ +| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| int max_peerlist_size = state->max_peerlist_size; | │ │ │ │ │ +|std::uint16_t session_impl::ssl_listen_port() const | │ │ │ │ │ +|{ | │ │ │ │ │ +| return ssl_listen_port(nullptr); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|for (int iterations = std::min(int(m_peers.size()), 300); | │ │ │ │ │ -|iterations > 0; --iterations) | │ │ │ │ │ +| std::uint16_t session_impl::ssl_listen_port(listen_socket_t* sock) const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| if (sock) | │ │ │ │ │ | { | │ │ │ │ │ -| ++state->loop_counter; | │ │ │ │ │ +| if (!(sock->flags & listen_socket_t::accept_incoming)) return 0; | │ │ │ │ │ +| return std::uint16_t(sock->tcp_external_port()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (m_round_robin >= int(m_peers.size())) m_round_robin = 0; | │ │ │ │ │ +| if (m_settings.get_int(settings_pack::proxy_type) != settings_pack::none | │ │ │ │ │ +| && m_settings.get_bool(settings_pack::proxy_peer_connections)) | │ │ │ │ │ +| return 0; | │ │ │ │ │ | | │ │ │ │ │ -| torrent_peer& pe = *m_peers[m_round_robin]; | │ │ │ │ │ -| TORRENT_ASSERT(pe.in_use); | │ │ │ │ │ -| int current = m_round_robin; | │ │ │ │ │ +| for (auto const& s : m_listen_sockets) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!(s->flags & listen_socket_t::accept_incoming)) continue; | │ │ │ │ │ +| if (s->ssl == transport::ssl) | │ │ │ │ │ +| return std::uint16_t(s->tcp_external_port()); | │ │ │ │ │ +| } | │ │ │ │ │ +|#else | │ │ │ │ │ +| TORRENT_UNUSED(sock); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| return 0; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // if the number of peers is growing large | │ │ │ │ │ -| // we need to start weeding. | │ │ │ │ │ +|_ _i_n_t_ _s_e_s_s_i_o_n___i_m_p_l_:_:_g_e_t___l_i_s_t_e_n___p_o_r_t_(_t_r_a_n_s_p_o_r_t_ _c_o_n_s_t_ _s_s_l_,_ _a_u_x_:_:_l_i_s_t_e_n___s_o_c_k_e_t___h_a_n_d_l_e_ _c_o_n_s_t_&_ _s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_6_3_9_0_ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _b_e_ _f_a_c_t_o_r_e_d_ _i_n_t_o_ _t_h_e_ _u_d_p_ _s_o_c_k_e_t_,_ _s_o_ _w_e_ _o_n_l_y_ _h_a_v_e_ _t_h_e_ _c_o_d_e_ _o_n_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd bbee ffaaccttoorreedd iinnttoo tthhee uuddpp ssoocckkeett,, ssoo wwee oonnllyy hhaavvee tthhee ccooddee oonnccee ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::66339900 ****** | │ │ │ │ │ +|return upload_rate_limit(m_local_peer_class); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (int(m_peers.size()) >= max_peerlist_size * 0.95 | │ │ │ │ │ -| && max_peerlist_size > 0) | │ │ │ │ │ +| int session_impl::local_download_rate_limit() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return download_rate_limit(m_local_peer_class); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| int session_impl::upload_rate_limit_depr() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return upload_rate_limit(m_global_class); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| int session_impl::download_rate_limit_depr() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return download_rate_limit(m_global_class); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif // DEPRECATE | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|void session_impl::update_peer_dscp() | │ │ │ │ │ +|{ | │ │ │ │ │ +| int const value = m_settings.get_int(settings_pack::peer_dscp); | │ │ │ │ │ +| for (auto const& l : m_listen_sockets) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (l->sock) | │ │ │ │ │ | { | │ │ │ │ │ -| if (is_erase_candidate(pe) | │ │ │ │ │ -| && (erase_candidate == -1 | │ │ │ │ │ -| || !compare_peer_erase(*m_peers[erase_candidate], pe))) | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| set_traffic_class(*l->sock, value, ec); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ | { | │ │ │ │ │ -| if (should_erase_immediately(pe)) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (erase_candidate > current) --erase_candidate; | │ │ │ │ │ -| erase_peer(m_peers.begin() + current, state); | │ │ │ │ │ -| continue; | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| erase_candidate = current; | │ │ │ │ │ -|_ _ _ _ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| session_log(">>> SET_DSCP [ tcp (%s %d) value: %x e: %s ]" | │ │ │ │ │ +| , l->sock->local_endpoint().address().to_string().c_str() | │ │ │ │ │ +| , l->sock->local_endpoint().port(), value, ec.message().c_str()); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| if (l->udp_sock) | │ │ │ │ │ +| { | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| set_traffic_class(l->udp_sock->sock, value, ec); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| { | │ │ │ │ │ +| session_log(">>> SET_DSCP [ udp (%s %d) value: %x e: %s ]" | │ │ │ │ │ +| , l->udp_sock->sock.local_endpoint().address().to_string().c_str() | │ │ │ │ │ +|_ _ _ _ _ _ _,_ _l_-_>_u_d_p___s_o_c_k_-_>_s_o_c_k_._l_o_c_a_l___p_o_r_t_(_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _2_|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/_n_o_d_e_._c_p_p_:_6_8_4_ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _h_a_v_e_ _a_ _b_i_a_s_ _t_o_w_a_r_d_s_ _n_o_d_e_-_i_d_ _p_r_e_f_i_x_e_s_ _t_h_a_t_ _a_r_e_ _m_i_s_s_i_n_g_ _i_n_ _t_h_e_ _b_u_c_k_e_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** iitt wwoouulldd bbee nniiccee ttoo hhaavvee aa bbiiaass ttoowwaarrddss nnooddee--iidd pprreeffiixxeess tthhaatt aarree mmiissssiinngg iinn tthhee bbuucckkeett ********** | │ │ │ │ │ |****** ....//ssrrcc//kkaaddeemmlliiaa//nnooddee..ccpppp::668844 ****** | │ │ │ │ │ |node_entry const* ne = m_table.next_refresh(); | │ │ │ │ │ | if (ne == nullptr) return; | │ │ │ │ │ | | │ │ │ │ │ | // this shouldn't happen | │ │ │ │ │ @@ -4084,69 +4084,14 @@ │ │ │ │ │ |entry write_nodes_entry(std::vector const& nodes) | │ │ │ │ │ |{ | │ │ │ │ │ | entry r; | │ │ │ │ │ | std::back_insert_iterator out(r.string()); | │ │ │ │ │ | for (auto const& n : nodes) | │ │ │ │ │ | { | │ │ │ │ │ |_ _ _s_t_d_:_:_c_o_p_y_(_n_._i_d_._b_e_g_i_n_(_)_,_ _n_._i_d_._e_n_d_(_)_,_ _o_u_t_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |make this configurable in dht_settings | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_d_h_t___s_t_o_r_a_g_e_._c_p_p_:_8_7_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmaakkee tthhiiss ccoonnffiigguurraabbllee iinn ddhhtt__sseettttiinnggss ********** | │ │ │ │ │ -|****** ....//ssrrcc//kkaaddeemmlliiaa//ddhhtt__ssttoorraaggee..ccpppp::8877 ****** | │ │ │ │ │ -|tcp::endpoint addr; | │ │ │ │ │ -| bool seed = 0; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| // internal | │ │ │ │ │ -| bool operator<(peer_entry const& lhs, peer_entry const& rhs) | │ │ │ │ │ -| { | │ │ │ │ │ -| return lhs.addr.address() == rhs.addr.address() | │ │ │ │ │ -| ? lhs.addr.port() < rhs.addr.port() | │ │ │ │ │ -| : lhs.addr.address() < rhs.addr.address(); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // this is a group. It contains a set of group members | │ │ │ │ │ -| struct torrent_entry | │ │ │ │ │ -| { | │ │ │ │ │ -| std::string name; | │ │ │ │ │ -| std::vector peers4; | │ │ │ │ │ -| std::vector peers6; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -|constexpr time_duration announce_interval = minutes(30); | │ │ │ │ │ -| | │ │ │ │ │ -| struct dht_immutable_item | │ │ │ │ │ -| { | │ │ │ │ │ -| // the actual value | │ │ │ │ │ -| std::unique_ptr value; | │ │ │ │ │ -| // this counts the number of IPs we have seen | │ │ │ │ │ -| // announcing this item, this is used to determine | │ │ │ │ │ -| // popularity if we reach the limit of items to store | │ │ │ │ │ -| bloom_filter<128> ips; | │ │ │ │ │ -| // the last time we heard about this item | │ │ │ │ │ -| // the correct interpretation of this field | │ │ │ │ │ -| // requires a time reference | │ │ │ │ │ -| time_point last_seen; | │ │ │ │ │ -| // number of IPs in the bloom filter | │ │ │ │ │ -| int num_announcers = 0; | │ │ │ │ │ -| // size of malloced space pointed to by value | │ │ │ │ │ -| int size = 0; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| struct dht_mutable_item : dht_immutable_item | │ │ │ │ │ -| { | │ │ │ │ │ -| signature sig{}; | │ │ │ │ │ -| sequence_number seq{}; | │ │ │ │ │ -| public_key key{}; | │ │ │ │ │ -| std::string salt; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| void set_value(dht_immutable_item& item, span buf) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _i_n_t_ _c_o_n_s_t_ _s_i_z_e_ _=_ _i_n_t_(_b_u_f_._s_i_z_e_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 2|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |use the non deprecated function instead of this one | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_3_0_5_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** uussee tthhee nnoonn ddeepprreeccaatteedd ffuunnccttiioonn iinnsstteeaadd ooff tthhiiss oonnee ********** | │ │ │ │ │ |****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::330055 ****** | │ │ │ │ │ |static const aux::array size_exceptions{{{16, 8, 4, 2}}}; | │ │ │ │ │ | if (bucket < size_exceptions.end_index()) | │ │ │ │ │ | return m_bucket_size * size_exceptions[bucket]; | │ │ │ │ │ @@ -4226,14 +4171,69 @@ │ │ │ │ │ | { | │ │ │ │ │ | // this entry belongs in the new bucket | │ │ │ │ │ | if (j->pinged() && int(new_bucket.size()) < new_bucket_size) | │ │ │ │ │ | new_bucket.push_back(*j); | │ │ │ │ │ | else | │ │ │ │ │ | new_replacement_bucket.push_back(*j); | │ │ │ │ │ |_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |make this configurable in dht_settings | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_d_h_t___s_t_o_r_a_g_e_._c_p_p_:_8_7_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmaakkee tthhiiss ccoonnffiigguurraabbllee iinn ddhhtt__sseettttiinnggss ********** | │ │ │ │ │ +|****** ....//ssrrcc//kkaaddeemmlliiaa//ddhhtt__ssttoorraaggee..ccpppp::8877 ****** | │ │ │ │ │ +|tcp::endpoint addr; | │ │ │ │ │ +| bool seed = 0; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| // internal | │ │ │ │ │ +| bool operator<(peer_entry const& lhs, peer_entry const& rhs) | │ │ │ │ │ +| { | │ │ │ │ │ +| return lhs.addr.address() == rhs.addr.address() | │ │ │ │ │ +| ? lhs.addr.port() < rhs.addr.port() | │ │ │ │ │ +| : lhs.addr.address() < rhs.addr.address(); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // this is a group. It contains a set of group members | │ │ │ │ │ +| struct torrent_entry | │ │ │ │ │ +| { | │ │ │ │ │ +| std::string name; | │ │ │ │ │ +| std::vector peers4; | │ │ │ │ │ +| std::vector peers6; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +|constexpr time_duration announce_interval = minutes(30); | │ │ │ │ │ +| | │ │ │ │ │ +| struct dht_immutable_item | │ │ │ │ │ +| { | │ │ │ │ │ +| // the actual value | │ │ │ │ │ +| std::unique_ptr value; | │ │ │ │ │ +| // this counts the number of IPs we have seen | │ │ │ │ │ +| // announcing this item, this is used to determine | │ │ │ │ │ +| // popularity if we reach the limit of items to store | │ │ │ │ │ +| bloom_filter<128> ips; | │ │ │ │ │ +| // the last time we heard about this item | │ │ │ │ │ +| // the correct interpretation of this field | │ │ │ │ │ +| // requires a time reference | │ │ │ │ │ +| time_point last_seen; | │ │ │ │ │ +| // number of IPs in the bloom filter | │ │ │ │ │ +| int num_announcers = 0; | │ │ │ │ │ +| // size of malloced space pointed to by value | │ │ │ │ │ +| int size = 0; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| struct dht_mutable_item : dht_immutable_item | │ │ │ │ │ +| { | │ │ │ │ │ +| signature sig{}; | │ │ │ │ │ +| sequence_number seq{}; | │ │ │ │ │ +| public_key key{}; | │ │ │ │ │ +| std::string salt; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| void set_value(dht_immutable_item& item, span buf) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _i_n_t_ _c_o_n_s_t_ _s_i_z_e_ _=_ _i_n_t_(_b_u_f_._s_i_z_e_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |having 8 priority levels is probably excessive. It should probably be changed to 3 levels + dont-download | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_p_i_e_c_e___p_i_c_k_e_r_._h_p_p_:_6_6_8_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** hhaavviinngg 88 pprriioorriittyy lleevveellss iiss pprroobbaabbllyy eexxcceessssiivvee.. IItt sshhoouulldd pprroobbaabbllyy bbee cchhaannggeedd ttoo 33 lleevveellss ++ ddoonntt--ddoowwnnllooaadd ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppiieeccee__ppiicckkeerr..hhpppp::666688 ****** | │ │ │ │ │ |else if (state() == piece_full) | │ │ │ │ │ | state(piece_full_reverse); | │ │ │ │ │ | } | │ │ │ │ │ @@ -4390,14 +4390,69 @@ │ │ │ │ │ | using allocator_type = typename boost::asio::associated_allocator::type; | │ │ │ │ │ | using executor_type = typename boost::asio::associated_executor::type; | │ │ │ │ │ | | │ │ │ │ │ | allocator_type get_allocator() const noexcept | │ │ │ │ │ | { return boost::asio::get_associated_allocator(m_underlying_handler); } | │ │ │ │ │ | | │ │ │ │ │ |_ _e_x_e_c_u_t_o_r___t_y_p_e_ _g_e_t___e_x_e_c_u_t_o_r_(_)_ _c_o_n_s_t_ _n_o_e_x_c_e_p_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |add async_connect() that takes a hostname and port as well | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_o_c_k_s_5___s_t_r_e_a_m_._h_p_p_:_1_5_3_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aadddd aassyynncc__ccoonnnneecctt(()) tthhaatt ttaakkeess aa hhoossttnnaammee aanndd ppoorrtt aass wweellll ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssoocckkss55__ssttrreeaamm..hhpppp::115533 ****** | │ │ │ │ │ +|TORRENT_ASSERT(!aux::is_ip_address(host)); | │ │ │ │ │ +| m_dst_name = host; | │ │ │ │ │ +| if (m_dst_name.size() > 255) | │ │ │ │ │ +| m_dst_name.resize(255); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void close(error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_dst_name.clear(); | │ │ │ │ │ +| proxy_base::close(ec); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ +| void close() | │ │ │ │ │ +| { | │ │ │ │ │ +| m_dst_name.clear(); | │ │ │ │ │ +| proxy_base::close(); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|template | │ │ │ │ │ +|void async_connect(endpoint_type const& endpoint, Handler handler) | │ │ │ │ │ +| { | │ │ │ │ │ +| // make sure we don't try to connect to INADDR_ANY. binding is fine, | │ │ │ │ │ +| // and using a hostname is fine on SOCKS version 5. | │ │ │ │ │ +| TORRENT_ASSERT(endpoint.address() != address() | │ │ │ │ │ +| || (!m_dst_name.empty() && m_version == 5)); | │ │ │ │ │ +| | │ │ │ │ │ +| m_remote_endpoint = endpoint; | │ │ │ │ │ +| | │ │ │ │ │ +| // the connect is split up in the following steps: | │ │ │ │ │ +| // 1. resolve name of proxy server | │ │ │ │ │ +| // 2. connect to proxy server | │ │ │ │ │ +| // 3. if version == 5: | │ │ │ │ │ +| // 3.1 send SOCKS5 authentication method message | │ │ │ │ │ +| // 3.2 read SOCKS5 authentication response | │ │ │ │ │ +| // 3.3 send username+password | │ │ │ │ │ +| // 4. send SOCKS command message | │ │ │ │ │ +| | │ │ │ │ │ +| ADD_OUTSTANDING_ASYNC("socks5_stream::name_lookup"); | │ │ │ │ │ +| m_resolver.async_resolve(m_hostname, to_string(m_port).data(), wrap_allocator( | │ │ │ │ │ +| [this](error_code const& ec, tcp::resolver::results_type ips, Handler hn) { | │ │ │ │ │ +| name_lookup(ec, std::move(ips), std::move(hn)); | │ │ │ │ │ +| }, std::move(handler))); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|private: | │ │ │ │ │ +| | │ │ │ │ │ +| template | │ │ │ │ │ +| void name_lookup(error_code const& e, tcp::resolver::results_type ips | │ │ │ │ │ +|_ _ _,_ _H_a_n_d_l_e_r_ _h_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |this should really be a circular buffer | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._h_p_p_:_9_9_6_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tthhiiss sshhoouulldd rreeaallllyy bbee aa cciirrccuullaarr bbuuffffeerr ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppeeeerr__ccoonnnneeccttiioonn..hhpppp::999966 ****** | │ │ │ │ │ |// it just serves as a queue to remember what we've sent, to avoid | │ │ │ │ │ | // re-sending suggests for the same piece | │ │ │ │ │ | // i.e. outgoing suggest pieces | │ │ │ │ │ @@ -4497,69 +4552,69 @@ │ │ │ │ │ | // and false if we got an incoming connection | │ │ │ │ │ | // could be considered: true = local, false = remote | │ │ │ │ │ | bool m_outgoing:1; | │ │ │ │ │ | | │ │ │ │ │ | // is true if we learn the incoming connections listening | │ │ │ │ │ | // during the extended handshake | │ │ │ │ │ |_ _ _b_o_o_l_ _m___r_e_c_e_i_v_e_d___l_i_s_t_e_n___p_o_r_t_:_1_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |add async_connect() that takes a hostname and port as well | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_o_c_k_s_5___s_t_r_e_a_m_._h_p_p_:_1_5_3_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aadddd aassyynncc__ccoonnnneecctt(()) tthhaatt ttaakkeess aa hhoossttnnaammee aanndd ppoorrtt aass wweellll ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssoocckkss55__ssttrreeaamm..hhpppp::115533 ****** | │ │ │ │ │ -|TORRENT_ASSERT(!aux::is_ip_address(host)); | │ │ │ │ │ -| m_dst_name = host; | │ │ │ │ │ -| if (m_dst_name.size() > 255) | │ │ │ │ │ -| m_dst_name.resize(255); | │ │ │ │ │ -| } | │ │ │ │ │ +|relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |this type should probably be renamed to send_buffer | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_c_h_a_i_n_e_d___b_u_f_f_e_r_._h_p_p_:_5_9_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ttyyppee sshhoouulldd pprroobbaabbllyy bbee rreennaammeedd ttoo sseenndd__bbuuffffeerr ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//cchhaaiinneedd__bbuuffffeerr..hhpppp::5599 ****** | │ │ │ │ │ +|#include "libtorrent/aux_/buffer.hpp" | │ │ │ │ │ | | │ │ │ │ │ -| void close(error_code& ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_dst_name.clear(); | │ │ │ │ │ -| proxy_base::close(ec); | │ │ │ │ │ -| } | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ -| void close() | │ │ │ │ │ -| { | │ │ │ │ │ -| m_dst_name.clear(); | │ │ │ │ │ -| proxy_base::close(); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ | | │ │ │ │ │ -|template | │ │ │ │ │ -|void async_connect(endpoint_type const& endpoint, Handler handler) | │ │ │ │ │ -| { | │ │ │ │ │ -| // make sure we don't try to connect to INADDR_ANY. binding is fine, | │ │ │ │ │ -| // and using a hostname is fine on SOCKS version 5. | │ │ │ │ │ -| TORRENT_ASSERT(endpoint.address() != address() | │ │ │ │ │ -| || (!m_dst_name.empty() && m_version == 5)); | │ │ │ │ │ +|#ifdef _MSC_VER | │ │ │ │ │ +|// visual studio requires the value in a deque to be copyable. C++11 | │ │ │ │ │ +|// has looser requirements depending on which functions are actually used. | │ │ │ │ │ +|#define TORRENT_CPP98_DEQUE 1 | │ │ │ │ │ +|#else | │ │ │ │ │ +|#define TORRENT_CPP98_DEQUE 0 | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| m_remote_endpoint = endpoint; | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ +|namespace aux { | │ │ │ │ │ | | │ │ │ │ │ -| // the connect is split up in the following steps: | │ │ │ │ │ -| // 1. resolve name of proxy server | │ │ │ │ │ -| // 2. connect to proxy server | │ │ │ │ │ -| // 3. if version == 5: | │ │ │ │ │ -| // 3.1 send SOCKS5 authentication method message | │ │ │ │ │ -| // 3.2 read SOCKS5 authentication response | │ │ │ │ │ -| // 3.3 send username+password | │ │ │ │ │ -| // 4. send SOCKS command message | │ │ │ │ │ +|struct TORRENT_EXTRA_EXPORT chained_buffer : private single_threaded | │ │ │ │ │ +|{ | │ │ │ │ │ +| chained_buffer(): m_bytes(0), m_capacity(0) | │ │ │ │ │ +| { | │ │ │ │ │ +| thread_started(); | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| m_destructed = false; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| ADD_OUTSTANDING_ASYNC("socks5_stream::name_lookup"); | │ │ │ │ │ -| m_resolver.async_resolve(m_hostname, to_string(m_port).data(), wrap_allocator( | │ │ │ │ │ -| [this](error_code const& ec, tcp::resolver::results_type ips, Handler hn) { | │ │ │ │ │ -| name_lookup(ec, std::move(ips), std::move(hn)); | │ │ │ │ │ -| }, std::move(handler))); | │ │ │ │ │ -| } | │ │ │ │ │ +| private: | │ │ │ │ │ | | │ │ │ │ │ -|private: | │ │ │ │ │ +| // destructs/frees the holder object | │ │ │ │ │ +| using destruct_holder_fun = void (*)(void*); | │ │ │ │ │ +| using move_construct_holder_fun = void (*)(void*, void*); | │ │ │ │ │ | | │ │ │ │ │ -| template | │ │ │ │ │ -| void name_lookup(error_code const& e, tcp::resolver::results_type ips | │ │ │ │ │ -|_ _ _,_ _H_a_n_d_l_e_r_ _h_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| struct buffer_t | │ │ │ │ │ +| { | │ │ │ │ │ +| buffer_t() {} | │ │ │ │ │ +|#if TORRENT_CPP98_DEQUE | │ │ │ │ │ +| buffer_t(buffer_t&& rhs) noexcept | │ │ │ │ │ +| { | │ │ │ │ │ +| destruct_holder = rhs.destruct_holder; | │ │ │ │ │ +| move_holder = rhs.move_holder; | │ │ │ │ │ +| buf = rhs.buf; | │ │ │ │ │ +| size = rhs.size; | │ │ │ │ │ +| used_size = rhs.used_size; | │ │ │ │ │ +| move_holder(&holder, &rhs.holder); | │ │ │ │ │ +| } | │ │ │ │ │ +| buffer_t& operator=(buffer_t&& rhs) & noexcept | │ │ │ │ │ +|_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |make this interface a lot smaller. It could be split up into several smaller interfaces. Each subsystem could then limit the size of| │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_n_t_e_r_f_a_c_e_._h_p_p_:_1_2_7_ _ _ _ _ _|_t_h_e_ _m_o_c_k_ _o_b_j_e_c_t_ _t_o_ _t_e_s_t_ _i_t_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmaakkee tthhiiss iinntteerrffaaccee aa lloott ssmmaalllleerr.. IItt ccoouulldd bbee sspplliitt uupp iinnttoo sseevveerraall ssmmaalllleerr iinntteerrffaacceess.. EEaacchh ssuubbssyysstteemm ccoouulldd tthheenn lliimmiitt tthhee ssiizzee ooff tthhee mmoocckk oobbjjeecctt ttoo tteesstt iitt.. ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iinntteerrffaaccee..hhpppp::112277 ****** | │ │ │ │ │ |// a release build with logging disabled (which is the default) will | │ │ │ │ │ | // not have this class at all | │ │ │ │ │ | struct TORRENT_EXTRA_EXPORT session_logger | │ │ │ │ │ @@ -4635,123 +4690,14 @@ │ │ │ │ │ | | │ │ │ │ │ | virtual void remove_torrent(torrent_handle const& h, remove_flags_t options = {}) = 0; | │ │ │ │ │ | virtual void remove_torrent_impl(std::shared_ptr tptr, remove_flags_t options) = 0; | │ │ │ │ │ | | │ │ │ │ │ | // port filter | │ │ │ │ │ | virtual port_filter const& get_port_filter() const = 0; | │ │ │ │ │ |_ _ _v_i_r_t_u_a_l_ _v_o_i_d_ _b_a_n___i_p_(_a_d_d_r_e_s_s_ _a_d_d_r_)_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 2|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |this type should probably be renamed to send_buffer | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_c_h_a_i_n_e_d___b_u_f_f_e_r_._h_p_p_:_5_9_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ttyyppee sshhoouulldd pprroobbaabbllyy bbee rreennaammeedd ttoo sseenndd__bbuuffffeerr ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//cchhaaiinneedd__bbuuffffeerr..hhpppp::5599 ****** | │ │ │ │ │ -|#include "libtorrent/aux_/buffer.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -| | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|#ifdef _MSC_VER | │ │ │ │ │ -|// visual studio requires the value in a deque to be copyable. C++11 | │ │ │ │ │ -|// has looser requirements depending on which functions are actually used. | │ │ │ │ │ -|#define TORRENT_CPP98_DEQUE 1 | │ │ │ │ │ -|#else | │ │ │ │ │ -|#define TORRENT_CPP98_DEQUE 0 | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ -|namespace aux { | │ │ │ │ │ -| | │ │ │ │ │ -|struct TORRENT_EXTRA_EXPORT chained_buffer : private single_threaded | │ │ │ │ │ -|{ | │ │ │ │ │ -| chained_buffer(): m_bytes(0), m_capacity(0) | │ │ │ │ │ -| { | │ │ │ │ │ -| thread_started(); | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -| m_destructed = false; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| private: | │ │ │ │ │ -| | │ │ │ │ │ -| // destructs/frees the holder object | │ │ │ │ │ -| using destruct_holder_fun = void (*)(void*); | │ │ │ │ │ -| using move_construct_holder_fun = void (*)(void*, void*); | │ │ │ │ │ -| | │ │ │ │ │ -| struct buffer_t | │ │ │ │ │ -| { | │ │ │ │ │ -| buffer_t() {} | │ │ │ │ │ -|#if TORRENT_CPP98_DEQUE | │ │ │ │ │ -| buffer_t(buffer_t&& rhs) noexcept | │ │ │ │ │ -| { | │ │ │ │ │ -| destruct_holder = rhs.destruct_holder; | │ │ │ │ │ -| move_holder = rhs.move_holder; | │ │ │ │ │ -| buf = rhs.buf; | │ │ │ │ │ -| size = rhs.size; | │ │ │ │ │ -| used_size = rhs.used_size; | │ │ │ │ │ -| move_holder(&holder, &rhs.holder); | │ │ │ │ │ -| } | │ │ │ │ │ -| buffer_t& operator=(buffer_t&& rhs) & noexcept | │ │ │ │ │ -|_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _1_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_7_0_7_ _ _|_r_e_p_o_r_t_ _t_h_e_ _p_r_o_p_e_r_ _a_d_d_r_e_s_s_ _o_f_ _t_h_e_ _r_o_u_t_e_r_ _a_s_ _t_h_e_ _s_o_u_r_c_e_ _I_P_ _o_f_ _t_h_i_s_ _v_o_t_e_ _o_f_ _o_u_r_ _e_x_t_e_r_n_a_l_ _a_d_d_r_e_s_s_,_ _i_n_s_t_e_a_d_ _o_f_ _t_h_e_ _e_m_p_t_y_ _a_d_d_r_e_s_s_ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** rreeppoorrtt tthhee pprrooppeerr aaddddrreessss ooff tthhee rroouutteerr aass tthhee ssoouurrccee IIPP ooff tthhiiss vvoottee ooff oouurr eexxtteerrnnaall aaddddrreessss,, iinnsstteeaadd ooff tthhee eemmppttyy aaddddrreessss ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55770077 ****** | │ │ │ │ │ -|, listen_socket_handle const& ls) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| listen_socket_t* listen_socket = ls.get(); | │ │ │ │ │ -| | │ │ │ │ │ -| // NOTE: don't assume that if ec != 0, the rest of the logic | │ │ │ │ │ -| // is not necessary, the ports still need to be set, in other | │ │ │ │ │ -| // words, don't early return without careful review of the | │ │ │ │ │ -| // remaining logic | │ │ │ │ │ -| if (ec && m_alerts.should_post()) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_alerts.emplace_alert(mapping | │ │ │ │ │ -| , transport, ec, listen_socket ? listen_socket->local_endpoint.address() : address()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| if (!listen_socket) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (!ec && !external_ip.is_unspecified()) | │ │ │ │ │ -| { | │ │ │ │ │ -|listen_socket->external_address.cast_vote(external_ip, source_router, address()); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| // need to check whether this mapping is for one of session ports (it could also be a user mapping) | │ │ │ │ │ -| if ((proto == portmap_protocol::tcp) && (listen_socket->tcp_port_mapping[transport].mapping == mapping)) | │ │ │ │ │ -| listen_socket->tcp_port_mapping[transport].port = port; | │ │ │ │ │ -| else if ((proto == portmap_protocol::udp) && (listen_socket->udp_port_mapping[transport].mapping == mapping)) | │ │ │ │ │ -| listen_socket->udp_port_mapping[transport].port = port; | │ │ │ │ │ -| | │ │ │ │ │ -| if (!ec && m_alerts.should_post()) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_alerts.emplace_alert(mapping, port | │ │ │ │ │ -| , transport, proto, listen_socket->local_endpoint.address()); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| session_status session_impl::status() const | │ │ │ │ │ -| { | │ │ │ │ │ -|// INVARIANT_CHECK; | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| session_status s; | │ │ │ │ │ -| | │ │ │ │ │ -| s.optimistic_unchoke_counter = m_optimistic_unchoke_time_scaler; | │ │ │ │ │ -| s.unchoke_counter = m_unchoke_time_scaler; | │ │ │ │ │ -| s.num_dead_peers = int(m_undead_peers.size()); | │ │ │ │ │ -| | │ │ │ │ │ -| s.num_peers = int(m_stats_counters[counters::num_peers_connected]); | │ │ │ │ │ -| s.num_unchoked = int(m_stats_counters[counters::num_peers_up_unchoked_all]); | │ │ │ │ │ -|_ _ _s_._a_l_l_o_w_e_d___u_p_l_o_a_d___s_l_o_t_s_ _=_ _i_n_t_(_m___s_t_a_t_s___c_o_u_n_t_e_r_s_[_c_o_u_n_t_e_r_s_:_:_n_u_m___u_n_c_h_o_k_e___s_l_o_t_s_]_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ | | |make this depend on the error and on the filesystem the files are being downloaded to. If the error is no_space_left_on_device and | │ │ │ │ │ |relevance 1|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_1_2_6 |the filesystem doesn't support sparse files, only zero the priorities of the pieces that are at the tails of all files, leaving | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_e_v_e_r_y_t_h_i_n_g_ _u_p_ _t_o_ _t_h_e_ _h_i_g_h_e_s_t_ _w_r_i_t_t_e_n_ _p_i_e_c_e_ _i_n_ _e_a_c_h_ _f_i_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmaakkee tthhiiss ddeeppeenndd oonn tthhee eerrrroorr aanndd oonn tthhee ffiilleessyysstteemm tthhee ffiilleess aarree bbeeiinngg ddoowwnnllooaaddeedd ttoo.. IIff tthhee eerrrroorr iiss nnoo__ssppaaccee__lleefftt__oonn__ddeevviiccee aanndd tthhee ffiilleessyysstteemm ddooeessnn''tt ssuuppppoorrtt ssppaarrssee | │ │ │ │ │ |ffiilleess,, oonnllyy zzeerroo tthhee pprriioorriittiieess ooff tthhee ppiieecceess tthhaatt aarree aatt tthhee ttaaiillss ooff aallll ffiilleess,, lleeaavviinngg eevveerryytthhiinngg uupp ttoo tthhee hhiigghheesstt wwrriitttteenn ppiieeccee iinn eeaacchh ffiillee ********** | │ │ │ │ │ |****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11112266 ****** | │ │ │ │ │ | // notify the user of the error | │ │ │ │ │ @@ -4853,14 +4799,68 @@ │ │ │ │ │ | // we need to keep the object alive during this operation | │ │ │ │ │ | m_ses.disk_thread().async_release_files(m_storage | │ │ │ │ │ | , std::bind(&torrent::on_cache_flushed, shared_from_this(), false)); | │ │ │ │ │ | m_ses.deferred_submit_jobs(); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ |_ _ _/_/_ _t_h_i_s_ _t_o_r_r_e_n_t_ _j_u_s_t_ _c_o_m_p_l_e_t_e_d_ _d_o_w_n_l_o_a_d_s_,_ _w_h_i_c_h_ _m_e_a_n_s_ _i_t_ _w_i_l_l_ _f_a_l_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _1_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_7_0_7_ _ _|_r_e_p_o_r_t_ _t_h_e_ _p_r_o_p_e_r_ _a_d_d_r_e_s_s_ _o_f_ _t_h_e_ _r_o_u_t_e_r_ _a_s_ _t_h_e_ _s_o_u_r_c_e_ _I_P_ _o_f_ _t_h_i_s_ _v_o_t_e_ _o_f_ _o_u_r_ _e_x_t_e_r_n_a_l_ _a_d_d_r_e_s_s_,_ _i_n_s_t_e_a_d_ _o_f_ _t_h_e_ _e_m_p_t_y_ _a_d_d_r_e_s_s_ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** rreeppoorrtt tthhee pprrooppeerr aaddddrreessss ooff tthhee rroouutteerr aass tthhee ssoouurrccee IIPP ooff tthhiiss vvoottee ooff oouurr eexxtteerrnnaall aaddddrreessss,, iinnsstteeaadd ooff tthhee eemmppttyy aaddddrreessss ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55770077 ****** | │ │ │ │ │ +|, listen_socket_handle const& ls) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| listen_socket_t* listen_socket = ls.get(); | │ │ │ │ │ +| | │ │ │ │ │ +| // NOTE: don't assume that if ec != 0, the rest of the logic | │ │ │ │ │ +| // is not necessary, the ports still need to be set, in other | │ │ │ │ │ +| // words, don't early return without careful review of the | │ │ │ │ │ +| // remaining logic | │ │ │ │ │ +| if (ec && m_alerts.should_post()) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_alerts.emplace_alert(mapping | │ │ │ │ │ +| , transport, ec, listen_socket ? listen_socket->local_endpoint.address() : address()); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| if (!listen_socket) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (!ec && !external_ip.is_unspecified()) | │ │ │ │ │ +| { | │ │ │ │ │ +|listen_socket->external_address.cast_vote(external_ip, source_router, address()); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| // need to check whether this mapping is for one of session ports (it could also be a user mapping) | │ │ │ │ │ +| if ((proto == portmap_protocol::tcp) && (listen_socket->tcp_port_mapping[transport].mapping == mapping)) | │ │ │ │ │ +| listen_socket->tcp_port_mapping[transport].port = port; | │ │ │ │ │ +| else if ((proto == portmap_protocol::udp) && (listen_socket->udp_port_mapping[transport].mapping == mapping)) | │ │ │ │ │ +| listen_socket->udp_port_mapping[transport].port = port; | │ │ │ │ │ +| | │ │ │ │ │ +| if (!ec && m_alerts.should_post()) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_alerts.emplace_alert(mapping, port | │ │ │ │ │ +| , transport, proto, listen_socket->local_endpoint.address()); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| session_status session_impl::status() const | │ │ │ │ │ +| { | │ │ │ │ │ +|// INVARIANT_CHECK; | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| session_status s; | │ │ │ │ │ +| | │ │ │ │ │ +| s.optimistic_unchoke_counter = m_optimistic_unchoke_time_scaler; | │ │ │ │ │ +| s.unchoke_counter = m_unchoke_time_scaler; | │ │ │ │ │ +| s.num_dead_peers = int(m_undead_peers.size()); | │ │ │ │ │ +| | │ │ │ │ │ +| s.num_peers = int(m_stats_counters[counters::num_peers_connected]); | │ │ │ │ │ +| s.num_unchoked = int(m_stats_counters[counters::num_peers_up_unchoked_all]); | │ │ │ │ │ +|_ _ _s_._a_l_l_o_w_e_d___u_p_l_o_a_d___s_l_o_t_s_ _=_ _i_n_t_(_m___s_t_a_t_s___c_o_u_n_t_e_r_s_[_c_o_u_n_t_e_r_s_:_:_n_u_m___u_n_c_h_o_k_e___s_l_o_t_s_]_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 1|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |have one instance per possible subnet, 192.168.x.x, 10.x.x.x, etc. | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_i_p___v_o_t_e_r_._h_p_p_:_1_3_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** hhaavvee oonnee iinnssttaannccee ppeerr ppoossssiibbllee ssuubbnneett,, 119922..116688..xx..xx,, 1100..xx..xx..xx,, eettcc.. ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//iipp__vvootteerr..hhpppp::113300 ****** | │ │ │ │ │ |// stores one address for each combination of local/global and ipv4/ipv6 | │ │ │ │ │ | // use of this class should be avoided, get the IP from the appropriate | │ │ │ │ │ | // listen interface wherever possible | │ │ │ │ │ @@ -4883,251 +4883,89 @@ │ │ │ │ │ | // [n][0] = IPv4 [n][1] = IPv6 | │ │ │ │ │ |address m_addresses[2][2]; | │ │ │ │ │ |}; | │ │ │ │ │ | | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ |_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___s_s_l_._c_p_p_:_4_0_7_ _ _ _ _ _ _|_t_e_s_t_ _u_s_i_n_g_ _a_ _s_i_g_n_e_d_ _c_e_r_t_i_f_i_c_a_t_e_ _w_i_t_h_ _t_h_e_ _w_r_o_n_g_ _i_n_f_o_-_h_a_s_h_ _i_n_ _D_N_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt uussiinngg aa ssiiggnneedd cceerrttiiffiiccaattee wwiitthh tthhee wwrroonngg iinnffoo--hhaasshh iinn DDNN ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ssssll..ccpppp::440077 ****** | │ │ │ │ │ -|// in verifying peers | │ │ │ │ │ -| ctx.set_verify_mode(context::verify_none, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("Failed to set SSL verify mode: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| TEST_CHECK(!ec); | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___b_l_o_o_m___f_i_l_t_e_r_._c_p_p_:|test size() | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_1_3_5_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ssiizzee(()) ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____bb_ll_oo_oo_mm____ff_ii_ll_tt_ee_rr_.._cc_pp_pp_::_11_33_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___b_l_o_o_m___f_i_l_t_e_r_._c_p_p_:|test clear() | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_1_3_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt cclleeaarr(()) ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__bblloooomm__ffiilltteerr..ccpppp::113366 ****** | │ │ │ │ │ +|sha1_hash k("\x01\x00\x02\x00 "); | │ │ │ │ │ +| TEST_CHECK(!filter.find(k)); | │ │ │ │ │ +| filter.set(k); | │ │ │ │ │ +| TEST_CHECK(filter.find(k)); | │ │ │ │ │ | | │ │ │ │ │ -| std::string certificate = combine_path("..", combine_path("ssl", "peer_certificate.pem")); | │ │ │ │ │ -| std::string private_key = combine_path("..", combine_path("ssl", "peer_private_key.pem")); | │ │ │ │ │ -| std::string dh_params = combine_path("..", combine_path("ssl", "dhparams.pem")); | │ │ │ │ │ +| std::uint8_t compare[4] = { 0x16, 0xff, 0x55, 0xaa}; | │ │ │ │ │ | | │ │ │ │ │ -| if (flags & invalid_certificate) | │ │ │ │ │ -| { | │ │ │ │ │ -| certificate = combine_path("..", combine_path("ssl", "invalid_peer_certificate.pem")); | │ │ │ │ │ -| private_key = combine_path("..", combine_path("ssl", "invalid_peer_private_key.pem")); | │ │ │ │ │ -| } | │ │ │ │ │ +| bits_out = filter.to_string(); | │ │ │ │ │ +| TEST_EQUAL(memcmp(compare, bits_out.c_str(), 4), 0); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ +|} // anonymous namespace | │ │ │ │ │ | | │ │ │ │ │ -|if (flags & (valid_certificate | invalid_certificate)) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("set_password_callback\n"); | │ │ │ │ │ -| ctx.set_password_callback( | │ │ │ │ │ -| [](std::size_t, context::password_purpose) { return "test"; } | │ │ │ │ │ -| , ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ +|TORRENT_TEST(bloom_filter) | │ │ │ │ │ +|{ | │ │ │ │ │ +| test_set_and_get(); | │ │ │ │ │ +| test_set_bits(); | │ │ │ │ │ +| test_count_zeroes(); | │ │ │ │ │ +| test_to_from_string(); | │ │ │ │ │ +| | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___m_e_r_k_l_e___t_r_e_e_._c_p_p_: |use structured bindings in C++17 | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_2_3_3_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee ssttrruuccttuurreedd bbiinnddiinnggss iinn CC++++1177 ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__mmeerrkkllee__ttrreeee..ccpppp::223333 ****** | │ │ │ │ │ +|mask[std::size_t(i)] = true; | │ │ │ │ │ +| t.load_sparse_tree(span(f).subspan(first_piece, num_pieces), mask, empty_verified); | │ │ │ │ │ +| int const end_piece_layer = first_piece + merkle_num_leafs(num_pieces); | │ │ │ │ │ +| for (int i = 0; i < end_piece_layer; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| std::printf("Failed to set certificate passphrase: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| TEST_CHECK(!ec); | │ │ │ │ │ -| return false; | │ │ │ │ │ +| TEST_CHECK(t.has_node(i)); | │ │ │ │ │ +| TEST_CHECK(t.compare_node(i, f[i])); | │ │ │ │ │ | } | │ │ │ │ │ -| std::printf("use_certificate_file \"%s\"\n", certificate.c_str()); | │ │ │ │ │ -| ctx.use_certificate_file(certificate, context::pem, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ +| for (int i = end_piece_layer; i < num_nodes; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| std::printf("Failed to set certificate file: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| TEST_CHECK(!ec); | │ │ │ │ │ -| return false; | │ │ │ │ │ +| TEST_CHECK(!t.has_node(i)); | │ │ │ │ │ | } | │ │ │ │ │ -| std::printf("use_private_key_file \"%s\"\n", private_key.c_str()); | │ │ │ │ │ -| ctx.use_private_key_file(private_key, context::pem, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("Failed to set private key: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| TEST_CHECK(!ec); | │ │ │ │ │ -|_ _ _ _r_e_t_u_r_n_ _f_a_l_s_e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___s_s_l_._c_p_p_:_5_0_9_ _ _ _ _ _ _|_a_l_s_o_ _t_e_s_t_ _u_s_i_n_g_ _a_ _h_a_s_h_ _t_h_a_t_ _r_e_f_e_r_s_ _t_o_ _a_ _v_a_l_i_d_ _t_o_r_r_e_n_t_ _b_u_t_ _t_h_a_t_ _d_i_f_f_e_r_s_ _f_r_o_m_ _t_h_e_ _S_N_I_ _h_a_s_h_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aallssoo tteesstt uussiinngg aa hhaasshh tthhaatt rreeffeerrss ttoo aa vvaalliidd ttoorrrreenntt bbuutt tthhaatt ddiiffffeerrss ffrroomm tthhee SSNNII hhaasshh ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ssssll..ccpppp::550099 ****** | │ │ │ │ │ -|print_alerts(ses1, "ses1", true, true, &on_alert); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("Failed SSL handshake: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| return false; | │ │ │ │ │ | } | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04" | │ │ │ │ │ -| " " // space for info-hash | │ │ │ │ │ -| "aaaaaaaaaaaaaaaaaaaa" // peer-id | │ │ │ │ │ -| "\0\0\0\x01\x02"; // interested | │ │ │ │ │ +|namespace { | │ │ │ │ │ +|void test_roundtrip(aux::merkle_tree const& t | │ │ │ │ │ +| , int const block_count | │ │ │ │ │ +| , int const blocks_per_piece) | │ │ │ │ │ +|{ | │ │ │ │ │ +|aux::vector mask; | │ │ │ │ │ +|std::vector tree; | │ │ │ │ │ +| std::tie(tree, mask) = t.build_sparse_vector(); | │ │ │ │ │ | | │ │ │ │ │ -| // fill in the info-hash | │ │ │ │ │ -| if (flags & valid_bittorrent_hash) | │ │ │ │ │ +| aux::merkle_tree t2(block_count, blocks_per_piece, f[0].data()); | │ │ │ │ │ +| t2.load_sparse_tree(tree, mask, empty_verified); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_CHECK(t.build_vector() == t2.build_vector()); | │ │ │ │ │ +| for (int i = 0; i < int(t.size()); ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| std::memcpy(handshake + 28, &t->info_hashes().v1[0], 20); | │ │ │ │ │ +| TEST_EQUAL(t[i], t2[i]); | │ │ │ │ │ +| TEST_EQUAL(t.has_node(i), t2.has_node(i)); | │ │ │ │ │ +| | │ │ │ │ │ +| if (!t.has_node(i)) | │ │ │ │ │ +| TEST_CHECK(t[i].is_all_zeros()); | │ │ │ │ │ +| if (!t2.has_node(i)) | │ │ │ │ │ +| TEST_CHECK(t2[i].is_all_zeros()); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_CHECK(t.compare_node(i, t2[i])); | │ │ │ │ │ +| TEST_CHECK(t2.compare_node(i, t[i])); | │ │ │ │ │ | } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -|std::generate(handshake + 28, handshake + 48, &rand); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| // fill in the peer-id | │ │ │ │ │ -| std::generate(handshake + 48, handshake + 68, &rand); | │ │ │ │ │ -| | │ │ │ │ │ -| std::printf("bittorrent handshake\n"); | │ │ │ │ │ -| boost::asio::write(ssl_sock, boost::asio::buffer(handshake, (sizeof(handshake) - 1)), ec); | │ │ │ │ │ -| print_alerts(ses1, "ses1", true, true, &on_alert); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("failed to write bittorrent handshake: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| char buf[68]; | │ │ │ │ │ -| std::printf("read bittorrent handshake\n"); | │ │ │ │ │ -| boost::asio::read(ssl_sock, boost::asio::buffer(buf, sizeof(buf)), ec); | │ │ │ │ │ -| print_alerts(ses1, "ses1", true, true, &on_alert); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("failed to read bittorrent handshake: %s\n" | │ │ │ │ │ -| , ec.message().c_str()); | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| if (memcmp(buf, "\x13" "BitTorrent protocol", 20) != 0) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::printf("invalid bittorrent handshake\n"); | │ │ │ │ │ -|_ _ _r_e_t_u_r_n_ _f_a_l_s_e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___u_p_n_p_._c_p_p_:_1_5_6_ _ _ _ _ _|_s_t_o_r_e_ _t_h_e_ _l_o_g_ _a_n_d_ _v_e_r_i_f_y_ _t_h_a_t_ _s_o_m_e_ _k_e_y_ _m_e_s_s_a_g_e_s_ _a_r_e_ _t_h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssttoorree tthhee lloogg aanndd vveerriiffyy tthhaatt ssoommee kkeeyy mmeessssaaggeess aarree tthheerree ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__uuppnnpp..ccpppp::115566 ****** | │ │ │ │ │ -|, portmap_protocol const protocol, error_code const& err | │ │ │ │ │ -| , portmap_transport, aux::listen_socket_handle const&) override | │ │ │ │ │ -| { | │ │ │ │ │ -| callback_info info = {mapping, port, err}; | │ │ │ │ │ -| callbacks.push_back(info); | │ │ │ │ │ -| std::cout << "mapping: " << static_cast(mapping) | │ │ │ │ │ -| << ", port: " << port << ", IP: " << ip | │ │ │ │ │ -| << ", proto: " << static_cast(protocol) | │ │ │ │ │ -| << ", error: \"" << err.message() << "\"\n"; | │ │ │ │ │ -| } | │ │ │ │ │ -| #ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| bool should_log_portmap(portmap_transport) const override | │ │ │ │ │ -| { | │ │ │ │ │ -| return true; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void log_portmap(portmap_transport, char const* msg | │ │ │ │ │ -| , aux::listen_socket_handle const&) const override | │ │ │ │ │ -| { | │ │ │ │ │ -| std::cout << "UPnP: " << msg << std::endl; | │ │ │ │ │ -|} | │ │ │ │ │ -|#endif | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -|ip_interface pick_upnp_interface() | │ │ │ │ │ -|{ | │ │ │ │ │ -| lt::io_context ios; | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| std::vector const routes = enum_routes(ios, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::cerr << "failed to enumerate routes: " << ec.message() << '\n'; | │ │ │ │ │ -| TEST_CHECK(false); | │ │ │ │ │ -| return {}; | │ │ │ │ │ -| } | │ │ │ │ │ -| std::vector const ifs = enum_net_interfaces(ios, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::cerr << "failed to enumerate network interfaces: " << ec.message() << '\n'; | │ │ │ │ │ -| TEST_CHECK(false); | │ │ │ │ │ -| return {}; | │ │ │ │ │ -| } | │ │ │ │ │ -| int idx = 0; | │ │ │ │ │ -| for (auto const& face : ifs) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (!face.interface_address.is_v4()) continue; | │ │ │ │ │ -| std::cout << " - " << idx | │ │ │ │ │ -| << ' ' << face.interface_address.to_string() | │ │ │ │ │ -| << ' ' << int(static_cast(face.state)) | │ │ │ │ │ -| << ' ' << static_cast(face.flags) | │ │ │ │ │ -|_ _ _ _<_<_ _'_ _'_ _<_<_ _f_a_c_e_._n_a_m_e_ _<_<_ _'_\_n_'_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___b_l_o_o_m___f_i_l_t_e_r_._c_p_p_:|test size() | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_1_3_5_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ssiizzee(()) ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____bb_ll_oo_oo_mm____ff_ii_ll_tt_ee_rr_.._cc_pp_pp_::_11_33_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___b_l_o_o_m___f_i_l_t_e_r_._c_p_p_:|test clear() | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_1_3_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt cclleeaarr(()) ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__bblloooomm__ffiilltteerr..ccpppp::113366 ****** | │ │ │ │ │ -|sha1_hash k("\x01\x00\x02\x00 "); | │ │ │ │ │ -| TEST_CHECK(!filter.find(k)); | │ │ │ │ │ -| filter.set(k); | │ │ │ │ │ -| TEST_CHECK(filter.find(k)); | │ │ │ │ │ -| | │ │ │ │ │ -| std::uint8_t compare[4] = { 0x16, 0xff, 0x55, 0xaa}; | │ │ │ │ │ -| | │ │ │ │ │ -| bits_out = filter.to_string(); | │ │ │ │ │ -| TEST_EQUAL(memcmp(compare, bits_out.c_str(), 4), 0); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|} // anonymous namespace | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_TEST(bloom_filter) | │ │ │ │ │ -|{ | │ │ │ │ │ -| test_set_and_get(); | │ │ │ │ │ -| test_set_bits(); | │ │ │ │ │ -| test_count_zeroes(); | │ │ │ │ │ -| test_to_from_string(); | │ │ │ │ │ -| | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___m_e_r_k_l_e___t_r_e_e_._c_p_p_: |use structured bindings in C++17 | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_2_3_3_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee ssttrruuccttuurreedd bbiinnddiinnggss iinn CC++++1177 ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__mmeerrkkllee__ttrreeee..ccpppp::223333 ****** | │ │ │ │ │ -|mask[std::size_t(i)] = true; | │ │ │ │ │ -| t.load_sparse_tree(span(f).subspan(first_piece, num_pieces), mask, empty_verified); | │ │ │ │ │ -| int const end_piece_layer = first_piece + merkle_num_leafs(num_pieces); | │ │ │ │ │ -| for (int i = 0; i < end_piece_layer; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| TEST_CHECK(t.has_node(i)); | │ │ │ │ │ -| TEST_CHECK(t.compare_node(i, f[i])); | │ │ │ │ │ -| } | │ │ │ │ │ -| for (int i = end_piece_layer; i < num_nodes; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| TEST_CHECK(!t.has_node(i)); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|namespace { | │ │ │ │ │ -|void test_roundtrip(aux::merkle_tree const& t | │ │ │ │ │ -| , int const block_count | │ │ │ │ │ -| , int const blocks_per_piece) | │ │ │ │ │ -|{ | │ │ │ │ │ -|aux::vector mask; | │ │ │ │ │ -|std::vector tree; | │ │ │ │ │ -| std::tie(tree, mask) = t.build_sparse_vector(); | │ │ │ │ │ -| | │ │ │ │ │ -| aux::merkle_tree t2(block_count, blocks_per_piece, f[0].data()); | │ │ │ │ │ -| t2.load_sparse_tree(tree, mask, empty_verified); | │ │ │ │ │ -| | │ │ │ │ │ -| TEST_CHECK(t.build_vector() == t2.build_vector()); | │ │ │ │ │ -| for (int i = 0; i < int(t.size()); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| TEST_EQUAL(t[i], t2[i]); | │ │ │ │ │ -| TEST_EQUAL(t.has_node(i), t2.has_node(i)); | │ │ │ │ │ -| | │ │ │ │ │ -| if (!t.has_node(i)) | │ │ │ │ │ -| TEST_CHECK(t[i].is_all_zeros()); | │ │ │ │ │ -| if (!t2.has_node(i)) | │ │ │ │ │ -| TEST_CHECK(t2[i].is_all_zeros()); | │ │ │ │ │ -| | │ │ │ │ │ -| TEST_CHECK(t.compare_node(i, t2[i])); | │ │ │ │ │ -| TEST_CHECK(t2.compare_node(i, t[i])); | │ │ │ │ │ -| } | │ │ │ │ │ -|} | │ │ │ │ │ +|} | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ |TORRENT_TEST(roundtrip_empty_tree) | │ │ │ │ │ |{ | │ │ │ │ │ | aux::merkle_tree t(num_blocks, 1, f[0].data()); | │ │ │ │ │ | test_roundtrip(t, num_blocks, 1); | │ │ │ │ │ |} | │ │ │ │ │ @@ -5161,22 +4999,122 @@ │ │ │ │ │ | for (int i = 127; i < 127 + 4; ++i) | │ │ │ │ │ | TEST_CHECK(t[i] == f[i]); | │ │ │ │ │ | | │ │ │ │ │ | TEST_CHECK(t.verified_leafs() == none_set(num_blocks)); | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:|test file attributes | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_1_2_0_8_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ffiillee aattttrriibbuutteess ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_ii_ll_ee____ss_tt_oo_rr_aa_gg_ee_.._cc_pp_pp_::_11_22_00_88_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:|test symlinks | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_1_2_0_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ssyymmlliinnkkss ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_ii_ll_ee____ss_tt_oo_rr_aa_gg_ee_.._cc_pp_pp_::_11_22_00_99_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_l_a_g_s_._c_p_p_:_1_6_3 |change to a different test setup. currently always paused. test_set_after_add(torrent_flags::paused); test_unset_after_add | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_(_t_o_r_r_e_n_t___f_l_a_g_s_:_:_p_a_u_s_e_d_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** cchhaannggee ttoo aa ddiiffffeerreenntt tteesstt sseettuupp.. ccuurrrreennttllyy aallwwaayyss ppaauusseedd.. tteesstt__sseett__aafftteerr__aadddd((ttoorrrreenntt__ffllaaggss::::ppaauusseedd));; tteesstt__uunnsseett__aafftteerr__aadddd((ttoorrrreenntt__ffllaaggss::::ppaauusseedd));; ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ffllaaggss..ccpppp::116633 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| // share-mode | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::share_mode); | │ │ │ │ │ +| test_set_after_add(torrent_flags::share_mode); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::share_mode); | │ │ │ │ │ +|} | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_apply_ip_filter) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // apply-ip-filter | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::apply_ip_filter); | │ │ │ │ │ +| test_set_after_add(torrent_flags::apply_ip_filter); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::apply_ip_filter); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_paused) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // paused | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::paused); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_auto_managed) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // auto-managed | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::auto_managed); | │ │ │ │ │ +| test_set_after_add(torrent_flags::auto_managed); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::auto_managed); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|// super seeding mode is automatically turned off if we're not a seed | │ │ │ │ │ +|// since the posix_disk_io is not threaded, this will happen immediately | │ │ │ │ │ +|#if TORRENT_HAVE_MMAP | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_SUPERSEEDING | │ │ │ │ │ +|TORRENT_TEST(flag_super_seeding) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // super-seeding | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::super_seeding); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::super_seeding); | │ │ │ │ │ +| test_set_after_add(torrent_flags::super_seeding); | │ │ │ │ │ +|} | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_sequential_download) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // sequential-download | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::sequential_download); | │ │ │ │ │ +| test_set_after_add(torrent_flags::sequential_download); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::sequential_download); | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_l_a_g_s_._c_p_p_:_2_0_5 |this test is flaky, since the torrent will become ready before asking for the flags, and by then stop_when_ready will have been | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_c_l_e_a_r_e_d_ _t_e_s_t___a_d_d___a_n_d___g_e_t___f_l_a_g_s_(_t_o_r_r_e_n_t___f_l_a_g_s_:_:_s_t_o_p___w_h_e_n___r_e_a_d_y_)_;_ _s_e_t_t_i_n_g_ _s_t_o_p_-_w_h_e_n_-_r_e_a_d_y_ _w_h_e_n_ _a_l_r_e_a_d_y_ _s_t_o_p_p_e_d_ _h_a_s_ _n_o_ _e_f_f_e_c_t_._ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss tteesstt iiss ffllaakkyy,, ssiinnccee tthhee ttoorrrreenntt wwiillll bbeeccoommee rreeaaddyy bbeeffoorree aasskkiinngg ffoorr tthhee ffllaaggss,, aanndd bbyy tthheenn ssttoopp__wwhheenn__rreeaaddyy wwiillll hhaavvee bbeeeenn cclleeaarreedd tteesstt__aadddd__aanndd__ggeett__ffllaaggss | │ │ │ │ │ +|((ttoorrrreenntt__ffllaaggss::::ssttoopp__wwhheenn__rreeaaddyy));; sseettttiinngg ssttoopp--wwhheenn--rreeaaddyy wwhheenn aallrreeaaddyy ssttooppppeedd hhaass nnoo eeffffeecctt.. ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_ll_aa_gg_ss_.._cc_pp_pp_::_22_00_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___f_l_a_g_s_._c_p_p_:_2_0_9_ _ _ _ _|_c_h_a_n_g_e_ _t_o_ _a_ _d_i_f_f_e_r_e_n_t_ _t_e_s_t_ _s_e_t_u_p_._ _c_u_r_r_e_n_t_l_y_ _a_l_w_a_y_s_ _p_a_u_s_e_d_._ _t_e_s_t___s_e_t___a_f_t_e_r___a_d_d_(_t_o_r_r_e_n_t___f_l_a_g_s_:_:_s_t_o_p___w_h_e_n___r_e_a_d_y_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** cchhaannggee ttoo aa ddiiffffeerreenntt tteesstt sseettuupp.. ccuurrrreennttllyy aallwwaayyss ppaauusseedd.. tteesstt__sseett__aafftteerr__aadddd((ttoorrrreenntt__ffllaaggss::::ssttoopp__wwhheenn__rreeaaddyy));; ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ffllaaggss..ccpppp::220099 ****** | │ │ │ │ │ +|test_set_after_add(torrent_flags::super_seeding); | │ │ │ │ │ +|} | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_sequential_download) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // sequential-download | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::sequential_download); | │ │ │ │ │ +| test_set_after_add(torrent_flags::sequential_download); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::sequential_download); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|// the stop when ready flag will be cleared when the torrent is ready to start | │ │ │ │ │ +|// downloading. | │ │ │ │ │ +|// since the posix_disk_io is not threaded, this will happen immediately | │ │ │ │ │ +|#if TORRENT_HAVE_MMAP | │ │ │ │ │ +|TORRENT_TEST(flag_stop_when_ready) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // stop-when-ready | │ │ │ │ │ +|test_unset_after_add(torrent_flags::stop_when_ready); | │ │ │ │ │ +|} | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_disable_dht) | │ │ │ │ │ +|{ | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::disable_dht); | │ │ │ │ │ +| test_set_after_add(torrent_flags::disable_dht); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::disable_dht); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_disable_lsd) | │ │ │ │ │ +|{ | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::disable_lsd); | │ │ │ │ │ +| test_set_after_add(torrent_flags::disable_lsd); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::disable_lsd); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(flag_disable_pex) | │ │ │ │ │ +|{ | │ │ │ │ │ +| test_add_and_get_flags(torrent_flags::disable_pex); | │ │ │ │ │ +| test_set_after_add(torrent_flags::disable_pex); | │ │ │ │ │ +| test_unset_after_add(torrent_flags::disable_pex); | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_t_e_s_t_/_t_e_s_t___t_o_r_r_e_n_t___i_n_f_o_._c_p_p_:|test remap_files | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_4_5_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tteesstt rreemmaapp__ffiilleess ********** | │ │ │ │ │ |_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_oo_rr_rr_ee_nn_tt____ii_nn_ff_oo_.._cc_pp_pp_::_44_55_99_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_t_e_s_t_/_t_e_s_t___t_o_r_r_e_n_t___i_n_f_o_._c_p_p_:|torrent with 'p' (padfile) attribute | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_4_6_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ttoorrrreenntt wwiitthh ''pp'' ((ppaaddffiillee)) aattttrriibbuuttee ********** | │ │ │ │ │ @@ -5285,165 +5223,126 @@ │ │ │ │ │ | entry::list_type l; | │ │ │ │ │ | l.push_back(entry("http://foo.com/bar1")); | │ │ │ │ │ | l.push_back(entry("http://foo.com/bar1")); | │ │ │ │ │ | l.push_back(entry("http://foo.com/bar2")); | │ │ │ │ │ | entry const e(l); | │ │ │ │ │ | entry torrent; | │ │ │ │ │ |_ _t_o_r_r_e_n_t_[_"_u_r_l_-_l_i_s_t_"_]_ _=_ _e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_n_s_f_e_r_._c_p_p_:_1_7_3_ _|_t_h_e_s_e_ _s_e_t_t_i_n_g_s___p_a_c_k_ _t_e_s_t_s_ _b_e_l_o_n_g_ _i_n_ _t_h_e_i_r_ _o_w_n_ _t_e_s_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthheessee sseettttiinnggss__ppaacckk tteessttss bbeelloonngg iinn tthheeiirr oowwnn tteesstt ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ttrraannssffeerr..ccpppp::117733 ****** | │ │ │ │ │ -|// to the time it will take to complete the test | │ │ │ │ │ -| pack.set_int(settings_pack::min_reconnect_time, 0); | │ │ │ │ │ -| pack.set_int(settings_pack::stop_tracker_timeout, 1); | │ │ │ │ │ -| pack.set_bool(settings_pack::announce_to_all_trackers, true); | │ │ │ │ │ -| pack.set_bool(settings_pack::announce_to_all_tiers, true); | │ │ │ │ │ -| | │ │ │ │ │ -| // make sure we announce to both http and udp trackers | │ │ │ │ │ -| pack.set_bool(settings_pack::prefer_udp_trackers, false); | │ │ │ │ │ -| pack.set_bool(settings_pack::enable_outgoing_utp, false); | │ │ │ │ │ -| pack.set_bool(settings_pack::enable_incoming_utp, false); | │ │ │ │ │ -| pack.set_bool(settings_pack::enable_lsd, false); | │ │ │ │ │ -| pack.set_bool(settings_pack::enable_natpmp, false); | │ │ │ │ │ -| pack.set_bool(settings_pack::enable_upnp, false); | │ │ │ │ │ -| pack.set_bool(settings_pack::enable_dht, false); | │ │ │ │ │ -| | │ │ │ │ │ -| pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_disabled); | │ │ │ │ │ -| pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled); | │ │ │ │ │ -| | │ │ │ │ │ -| pack.set_bool(settings_pack::allow_multiple_connections_per_ip, false); | │ │ │ │ │ -| | │ │ │ │ │ -|pack.set_int(settings_pack::unchoke_slots_limit, 0); | │ │ │ │ │ -|ses1.apply_settings(pack); | │ │ │ │ │ -| TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == 0); | │ │ │ │ │ -| | │ │ │ │ │ -| pack.set_int(settings_pack::unchoke_slots_limit, -1); | │ │ │ │ │ -| ses1.apply_settings(pack); | │ │ │ │ │ -| TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == -1); | │ │ │ │ │ -| | │ │ │ │ │ -| pack.set_int(settings_pack::unchoke_slots_limit, 8); | │ │ │ │ │ -| ses1.apply_settings(pack); | │ │ │ │ │ -| TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == 8); | │ │ │ │ │ -| | │ │ │ │ │ -| ses2.apply_settings(pack); | │ │ │ │ │ -| | │ │ │ │ │ -| torrent_handle tor1; | │ │ │ │ │ -| torrent_handle tor2; | │ │ │ │ │ -| | │ │ │ │ │ -| create_directory("tmp1_transfer", ec); | │ │ │ │ │ -| std::ofstream file("tmp1_transfer/temporary"); | │ │ │ │ │ -| std::shared_ptr t = ::create_torrent(&file, "temporary", 32 * 1024, 13, false); | │ │ │ │ │ -| file.close(); | │ │ │ │ │ -| | │ │ │ │ │ -| TEST_CHECK(exists(combine_path("tmp1_transfer", "temporary"))); | │ │ │ │ │ -| | │ │ │ │ │ -| add_torrent_params params; | │ │ │ │ │ -| params.storage_mode = storage_mode; | │ │ │ │ │ -| params.flags &= ~torrent_flags::paused; | │ │ │ │ │ -| params.flags &= ~torrent_flags::auto_managed; | │ │ │ │ │ -| | │ │ │ │ │ -| wait_for_listen(ses1, "ses1"); | │ │ │ │ │ -|_ _w_a_i_t___f_o_r___l_i_s_t_e_n_(_s_e_s_2_,_ _"_s_e_s_2_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/ |test the case where we have > 120 samples (and have the base delay actually be updated) | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___t_i_m_e_s_t_a_m_p___h_i_s_t_o_r_y_._c_p_p_:_5_4_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt tthhee ccaassee wwhheerree wwee hhaavvee >> 112200 ssaammpplleess ((aanndd hhaavvee tthhee bbaassee ddeellaayy aaccttuuaallllyy bbee uuppddaatteedd)) ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_ii_mm_ee_ss_tt_aa_mm_pp____hh_ii_ss_tt_oo_rr_yy_.._cc_pp_pp_::_55_44_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/ |test the case where a sample is lower than the history entry but not lower than the base | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___t_i_m_e_s_t_a_m_p___h_i_s_t_o_r_y_._c_p_p_:_5_5_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt tthhee ccaassee wwhheerree aa ssaammppllee iiss lloowweerr tthhaann tthhee hhiissttoorryy eennttrryy bbuutt nnoott lloowweerr tthhaann tthhee bbaassee ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ttiimmeessttaammpp__hhiissttoorryy..ccpppp::5555 ****** | │ │ │ │ │ -|#include "libtorrent/aux_/timestamp_history.hpp" | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___s_s_l_._c_p_p_:_4_0_7_ _ _ _ _ _ _|_t_e_s_t_ _u_s_i_n_g_ _a_ _s_i_g_n_e_d_ _c_e_r_t_i_f_i_c_a_t_e_ _w_i_t_h_ _t_h_e_ _w_r_o_n_g_ _i_n_f_o_-_h_a_s_h_ _i_n_ _D_N_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt uussiinngg aa ssiiggnneedd cceerrttiiffiiccaattee wwiitthh tthhee wwrroonngg iinnffoo--hhaasshh iinn DDNN ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ssssll..ccpppp::440077 ****** | │ │ │ │ │ +|// in verifying peers | │ │ │ │ │ +| ctx.set_verify_mode(context::verify_none, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("Failed to set SSL verify mode: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| TEST_CHECK(!ec); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(timestamp_history) | │ │ │ │ │ -|{ | │ │ │ │ │ -| using namespace lt; | │ │ │ │ │ +| std::string certificate = combine_path("..", combine_path("ssl", "peer_certificate.pem")); | │ │ │ │ │ +| std::string private_key = combine_path("..", combine_path("ssl", "peer_private_key.pem")); | │ │ │ │ │ +| std::string dh_params = combine_path("..", combine_path("ssl", "dhparams.pem")); | │ │ │ │ │ | | │ │ │ │ │ -| aux::timestamp_history h; | │ │ │ │ │ -| TEST_EQUAL(h.add_sample(0x32, false), 0); | │ │ │ │ │ -| TEST_EQUAL(h.base(), 0x32); | │ │ │ │ │ -| TEST_EQUAL(h.add_sample(0x33, false), 0x1); | │ │ │ │ │ -| TEST_EQUAL(h.base(), 0x32); | │ │ │ │ │ -| TEST_EQUAL(h.add_sample(0x3433, false), 0x3401); | │ │ │ │ │ -| TEST_EQUAL(h.base(), 0x32); | │ │ │ │ │ -| TEST_EQUAL(h.add_sample(0x30, false), 0); | │ │ │ │ │ -| TEST_EQUAL(h.base(), 0x30); | │ │ │ │ │ +| if (flags & invalid_certificate) | │ │ │ │ │ +| { | │ │ │ │ │ +| certificate = combine_path("..", combine_path("ssl", "invalid_peer_certificate.pem")); | │ │ │ │ │ +| private_key = combine_path("..", combine_path("ssl", "invalid_peer_private_key.pem")); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // test that wrapping of the timestamp is properly handled | │ │ │ │ │ -| h.add_sample(0xfffffff3, false); | │ │ │ │ │ -| TEST_EQUAL(h.base(), 0xfffffff3); | │ │ │ │ │ | | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_0_ _ _ _|_t_e_s_t_ _s_c_r_a_p_e_ _r_e_q_u_e_s_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ssccrraappee rreeqquueessttss ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_00_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_1_ _ _ _|_t_e_s_t_ _p_a_r_s_e_ _p_e_e_r_s_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ppaarrssee ppeeeerrss66 ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_11_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_2_ _ _ _|_t_e_s_t_ _p_a_r_s_e_ _t_r_a_c_k_e_r_-_i_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ppaarrssee ttrraacckkeerr--iidd ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_22_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_3_ _ _ _|_t_e_s_t_ _p_a_r_s_e_ _f_a_i_l_u_r_e_-_r_e_a_s_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ppaarrssee ffaaiilluurree--rreeaassoonn ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_33_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_4 |test all failure paths, including invalid bencoding not a dictionary no files entry in scrape response no info-hash entry in scrape | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_r_e_s_p_o_n_s_e_ _m_a_l_f_o_r_m_e_d_ _p_e_e_r_s_ _i_n_ _p_e_e_r_ _l_i_s_t_ _o_f_ _d_i_c_t_i_o_n_a_r_i_e_s_ _u_n_e_v_e_n_ _n_u_m_b_e_r_ _o_f_ _b_y_t_e_s_ _i_n_ _p_e_e_r_s_ _a_n_d_ _p_e_e_r_s_6_ _s_t_r_i_n_g_ _r_e_s_p_o_n_s_e_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt aallll ffaaiilluurree ppaatthhss,, iinncclluuddiinngg iinnvvaalliidd bbeennccooddiinngg nnoott aa ddiiccttiioonnaarryy nnoo ffiilleess eennttrryy iinn ssccrraappee rreessppoonnssee nnoo iinnffoo--hhaasshh eennttrryy iinn ssccrraappee rreessppoonnssee mmaallffoorrmmeedd ppeeeerrss iinn ppeeeerr lliisstt| │ │ │ │ │ -|ooff ddiiccttiioonnaarriieess uunneevveenn nnuummbbeerr ooff bbyytteess iinn ppeeeerrss aanndd ppeeeerrss66 ssttrriinngg rreessppoonnsseess ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ttrraacckkeerr..ccpppp::6644 ****** | │ │ │ │ │ -|#include "test_utils.hpp" | │ │ │ │ │ -|#include "udp_tracker.hpp" | │ │ │ │ │ -|#include "settings.hpp" | │ │ │ │ │ -|#include "test_utils.hpp" | │ │ │ │ │ -|#include "libtorrent/alert.hpp" | │ │ │ │ │ -|#include "libtorrent/peer_info.hpp" // for peer_list_entry | │ │ │ │ │ -|#include "libtorrent/alert_types.hpp" | │ │ │ │ │ -|#include "libtorrent/session.hpp" | │ │ │ │ │ -|#include "libtorrent/session_params.hpp" | │ │ │ │ │ -|#include "libtorrent/error_code.hpp" | │ │ │ │ │ -|#include "libtorrent/tracker_manager.hpp" | │ │ │ │ │ -|#include "libtorrent/http_tracker_connection.hpp" // for parse_tracker_response | │ │ │ │ │ -|#include "libtorrent/torrent_info.hpp" | │ │ │ │ │ -|#include "libtorrent/announce_entry.hpp" | │ │ │ │ │ -|#include "libtorrent/torrent.hpp" | │ │ │ │ │ -|#include "libtorrent/aux_/path.hpp" | │ │ │ │ │ -|#include "libtorrent/socket_io.hpp" | │ │ │ │ │ +|if (flags & (valid_certificate | invalid_certificate)) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("set_password_callback\n"); | │ │ │ │ │ +| ctx.set_password_callback( | │ │ │ │ │ +| [](std::size_t, context::password_purpose) { return "test"; } | │ │ │ │ │ +| , ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("Failed to set certificate passphrase: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| TEST_CHECK(!ec); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ +| std::printf("use_certificate_file \"%s\"\n", certificate.c_str()); | │ │ │ │ │ +| ctx.use_certificate_file(certificate, context::pem, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("Failed to set certificate file: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| TEST_CHECK(!ec); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ +| std::printf("use_private_key_file \"%s\"\n", private_key.c_str()); | │ │ │ │ │ +| ctx.use_private_key_file(private_key, context::pem, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("Failed to set private key: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| TEST_CHECK(!ec); | │ │ │ │ │ +|_ _ _ _r_e_t_u_r_n_ _f_a_l_s_e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___s_s_l_._c_p_p_:_5_0_9_ _ _ _ _ _ _|_a_l_s_o_ _t_e_s_t_ _u_s_i_n_g_ _a_ _h_a_s_h_ _t_h_a_t_ _r_e_f_e_r_s_ _t_o_ _a_ _v_a_l_i_d_ _t_o_r_r_e_n_t_ _b_u_t_ _t_h_a_t_ _d_i_f_f_e_r_s_ _f_r_o_m_ _t_h_e_ _S_N_I_ _h_a_s_h_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aallssoo tteesstt uussiinngg aa hhaasshh tthhaatt rreeffeerrss ttoo aa vvaalliidd ttoorrrreenntt bbuutt tthhaatt ddiiffffeerrss ffrroomm tthhee SSNNII hhaasshh ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ssssll..ccpppp::550099 ****** | │ │ │ │ │ +|print_alerts(ses1, "ses1", true, true, &on_alert); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("Failed SSL handshake: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|using namespace lt; | │ │ │ │ │ +| char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04" | │ │ │ │ │ +| " " // space for info-hash | │ │ │ │ │ +| "aaaaaaaaaaaaaaaaaaaa" // peer-id | │ │ │ │ │ +| "\0\0\0\x01\x02"; // interested | │ │ │ │ │ | | │ │ │ │ │ +| // fill in the info-hash | │ │ │ │ │ +| if (flags & valid_bittorrent_hash) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::memcpy(handshake + 28, &t->info_hashes().v1[0], 20); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +|std::generate(handshake + 28, handshake + 48, &rand); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(parse_hostname_peers) | │ │ │ │ │ -|{ | │ │ │ │ │ -| char const response[] = "d5:peersld7:peer id20:aaaaaaaaaaaaaaaaaaaa" | │ │ │ │ │ -| "2:ip13:test_hostname4:porti1000eed" | │ │ │ │ │ -| "7:peer id20:bbbbabaababababababa2:ip12:another_host4:porti1001eeee"; | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| tracker_response resp = parse_tracker_response(response | │ │ │ │ │ -| , ec, {}, sha1_hash()); | │ │ │ │ │ +| // fill in the peer-id | │ │ │ │ │ +| std::generate(handshake + 48, handshake + 68, &rand); | │ │ │ │ │ | | │ │ │ │ │ -| TEST_EQUAL(ec, error_code()); | │ │ │ │ │ -| TEST_EQUAL(resp.peers.size(), 2); | │ │ │ │ │ -| if (resp.peers.size() == 2) | │ │ │ │ │ +| std::printf("bittorrent handshake\n"); | │ │ │ │ │ +| boost::asio::write(ssl_sock, boost::asio::buffer(handshake, (sizeof(handshake) - 1)), ec); | │ │ │ │ │ +| print_alerts(ses1, "ses1", true, true, &on_alert); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ | { | │ │ │ │ │ -| peer_entry const& e0 = resp.peers[0]; | │ │ │ │ │ -| peer_entry const& e1 = resp.peers[1]; | │ │ │ │ │ -| TEST_EQUAL(e0.hostname, "test_hostname"); | │ │ │ │ │ -| TEST_EQUAL(e0.port, 1000); | │ │ │ │ │ -| TEST_EQUAL(e0.pid, peer_id("aaaaaaaaaaaaaaaaaaaa")); | │ │ │ │ │ +| std::printf("failed to write bittorrent handshake: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| TEST_EQUAL(e1.hostname, "another_host"); | │ │ │ │ │ -| TEST_EQUAL(e1.port, 1001); | │ │ │ │ │ -| TEST_EQUAL(e1.pid, peer_id("bbbbabaababababababa")); | │ │ │ │ │ +| char buf[68]; | │ │ │ │ │ +| std::printf("read bittorrent handshake\n"); | │ │ │ │ │ +| boost::asio::read(ssl_sock, boost::asio::buffer(buf, sizeof(buf)), ec); | │ │ │ │ │ +| print_alerts(ses1, "ses1", true, true, &on_alert); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("failed to read bittorrent handshake: %s\n" | │ │ │ │ │ +| , ec.message().c_str()); | │ │ │ │ │ +| return false; | │ │ │ │ │ | } | │ │ │ │ │ -|} | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(parse_peers4) | │ │ │ │ │ -|{ | │ │ │ │ │ -| char const response[] = "d5:peers12:\x01\x02\x03\x04\x30\x10" | │ │ │ │ │ -| "\x09\x08\x07\x06\x20\x10" "e"; | │ │ │ │ │ -|_ _e_r_r_o_r___c_o_d_e_ _e_c_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| if (memcmp(buf, "\x13" "BitTorrent protocol", 20) != 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::printf("invalid bittorrent handshake\n"); | │ │ │ │ │ +|_ _ _r_e_t_u_r_n_ _f_a_l_s_e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/ |test sending invalid requests (out of bound piece index, offsets and sizes) | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___f_a_s_t___e_x_t_e_n_s_i_o_n_._c_p_p_:_1_1_3_5_ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt sseennddiinngg iinnvvaalliidd rreeqquueessttss ((oouutt ooff bboouunndd ppiieeccee iinnddeexx,, ooffffsseettss aanndd ssiizzeess)) ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_aa_ss_tt____ee_xx_tt_ee_nn_ss_ii_oo_nn_.._cc_pp_pp_::_11_11_33_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_t_e_s_t_/_t_e_s_t___p_e_e_r___l_i_s_t_._c_p_p_: |test erasing peers | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_1_2_4_1_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tteesstt eerraassiinngg ppeeeerrss ********** | │ │ │ │ │ |_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____pp_ee_ee_rr____ll_ii_ss_tt_.._cc_pp_pp_::_11_22_44_11_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_t_e_s_t_/_t_e_s_t___p_e_e_r___l_i_s_t_._c_p_p_: |test update_peer_port with allow_multiple_connections_per_ip and without | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_1_2_4_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tteesstt uuppddaattee__ppeeeerr__ppoorrtt wwiitthh aallllooww__mmuullttiippllee__ccoonnnneeccttiioonnss__ppeerr__iipp aanndd wwiitthhoouutt ********** | │ │ │ │ │ @@ -5472,232 +5371,14 @@ │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_1_2_4_8_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tteesstt ccoonnnneeccttiioonn__cclloosseedd ********** | │ │ │ │ │ |_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____pp_ee_ee_rr____ll_ii_ss_tt_.._cc_pp_pp_::_11_22_44_88_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_t_e_s_t_/_t_e_s_t___p_e_e_r___l_i_s_t_._c_p_p_: |connect candidates recalculation when incrementing failcount | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_1_2_4_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ccoonnnneecctt ccaannddiiddaatteess rreeccaallccuullaattiioonn wwhheenn iinnccrreemmeennttiinngg ffaaiillccoouunntt ********** | │ │ │ │ │ |_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____pp_ee_ee_rr____ll_ii_ss_tt_.._cc_pp_pp_::_11_22_44_99_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___d_h_t_._c_p_p_:_4_7_2_ _ _ _ _ _ _|_c_h_e_c_k_ _t_o_ _m_a_k_e_ _s_u_r_e_ _t_h_e_ _"_b_e_s_t_"_ _i_t_e_m_s_ _a_r_e_ _s_t_o_r_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** cchheecckk ttoo mmaakkee ssuurree tthhee ""bbeesstt"" iitteemmss aarree ssttoorreedd ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ddhhtt..ccpppp::447722 ****** | │ │ │ │ │ -|, msg_args().target(items[j].target)); | │ │ │ │ │ -| | │ │ │ │ │ -| key_desc_t const desc[] = | │ │ │ │ │ -| { | │ │ │ │ │ -| { "r", bdecode_node::dict_t, 0, key_desc_t::parse_children }, | │ │ │ │ │ -| { "v", bdecode_node::dict_t, 0, 0}, | │ │ │ │ │ -| { "id", bdecode_node::string_t, 20, key_desc_t::last_child}, | │ │ │ │ │ -| { "y", bdecode_node::string_t, 1, 0}, | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| bdecode_node parsed[4]; | │ │ │ │ │ -| char error_string[200]; | │ │ │ │ │ -| | │ │ │ │ │ -| int ret = verify_message(response, desc, parsed, error_string); | │ │ │ │ │ -| if (ret) | │ │ │ │ │ -| { | │ │ │ │ │ -| items_num.insert(items_num.begin(), j); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|TEST_EQUAL(items_num.size(), 4); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|int sum_distance_exp(int s, node_entry const& e, node_id const& ref) | │ │ │ │ │ -|{ | │ │ │ │ │ -| return s + distance_exp(e.id, ref); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|std::vector g_got_peers; | │ │ │ │ │ -| | │ │ │ │ │ -|void get_peers_cb(std::vector const& peers) | │ │ │ │ │ -|{ | │ │ │ │ │ -| g_got_peers.insert(g_got_peers.end(), peers.begin(), peers.end()); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|std::vector g_got_items; | │ │ │ │ │ -|dht::item g_put_item; | │ │ │ │ │ -|int g_put_count; | │ │ │ │ │ -| | │ │ │ │ │ -|void get_mutable_item_cb(dht::item const& i, bool a) | │ │ │ │ │ -|{ | │ │ │ │ │ -| if (!a) return; | │ │ │ │ │ -| if (!i.empty()) | │ │ │ │ │ -| g_got_items.push_back(i); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void put_mutable_item_data_cb(dht::item& i) | │ │ │ │ │ -|{ | │ │ │ │ │ -| if (!i.empty()) | │ │ │ │ │ -|_ _ _g___g_o_t___i_t_e_m_s_._p_u_s_h___b_a_c_k_(_i_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___d_h_t_._c_p_p_:_3_2_2_3_ _ _ _ _ _|_t_h_i_s_ _w_o_n_'_t_ _w_o_r_k_ _b_e_c_a_u_s_e_ _t_h_e_ _s_e_c_o_n_d_ _n_o_d_e_ _i_s_n_'_t_ _p_i_n_g_e_d_ _s_o_ _i_t_ _w_o_n_t_ _b_e_ _a_d_d_e_d_ _t_o_ _t_h_e_ _r_o_u_t_i_n_g_ _t_a_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss wwoonn''tt wwoorrkk bbeeccaauussee tthhee sseeccoonndd nnooddee iissnn''tt ppiinnggeedd ssoo iitt wwoonntt bbee aaddddeedd ttoo tthhee rroouuttiinngg ttaabbllee ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ddhhtt..ccpppp::33222233 ****** | │ │ │ │ │ -|bool ret = verify_message(request, get_item_desc_ro, parsed, error_string); | │ │ │ │ │ -| | │ │ │ │ │ -| TEST_CHECK(ret); | │ │ │ │ │ -| TEST_EQUAL(parsed[3].int_value(), 1); | │ │ │ │ │ -| | │ │ │ │ │ -| // should have one node now, which is 4.4.4.4:1234 | │ │ │ │ │ -| TEST_EQUAL(std::get<0>(node.size()), 1); | │ │ │ │ │ -| // and no replacement nodes | │ │ │ │ │ -| TEST_EQUAL(std::get<1>(node.size()), 0); | │ │ │ │ │ -| | │ │ │ │ │ -| // now, disable read_only, try again. | │ │ │ │ │ -| g_sent_packets.clear(); | │ │ │ │ │ -| sett.set_bool(settings_pack::dht_read_only, false); | │ │ │ │ │ -| | │ │ │ │ │ -| send_dht_request(node, "get", source, &response); | │ │ │ │ │ -| // sender should be added to replacement bucket | │ │ │ │ │ -| TEST_EQUAL(std::get<1>(node.size()), 1); | │ │ │ │ │ -| | │ │ │ │ │ -| g_sent_packets.clear(); | │ │ │ │ │ -|#if 0 | │ │ │ │ │ -|target = generate_next(); | │ │ │ │ │ -|node.get_item(target, get_immutable_item_cb); | │ │ │ │ │ -| | │ │ │ │ │ -| // since we have 2 nodes, we should have two packets. | │ │ │ │ │ -| TEST_EQUAL(g_sent_packets.size(), 2); | │ │ │ │ │ -| | │ │ │ │ │ -| // both of them shouldn't have a 'ro' key. | │ │ │ │ │ -| node_from_entry(g_sent_packets.front().second, request); | │ │ │ │ │ -| ret = verify_message(request, get_item_desc_ro, parsed, error_string); | │ │ │ │ │ -| | │ │ │ │ │ -| TEST_CHECK(ret); | │ │ │ │ │ -| TEST_CHECK(!parsed[3]); | │ │ │ │ │ -| | │ │ │ │ │ -| node_from_entry(g_sent_packets.back().second, request); | │ │ │ │ │ -| ret = verify_message(request, get_item_desc_ro, parsed, error_string); | │ │ │ │ │ -| | │ │ │ │ │ -| TEST_CHECK(ret); | │ │ │ │ │ -| TEST_CHECK(!parsed[3]); | │ │ │ │ │ -|#endif | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -|// these tests rely on logging being enabled | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_TEST(invalid_error_msg) | │ │ │ │ │ -|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___d_h_t_._c_p_p_:_4_0_8_1_ _ _ _ _ _|_t_e_s_t_ _o_b_f_u_s_c_a_t_e_d___g_e_t___p_e_e_r_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt oobbffuussccaatteedd__ggeett__ppeeeerrss ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ddhhtt..ccpppp::44008811 ****** | │ │ │ │ │ -|TEST_CHECK(sm.has_quota()); | │ │ │ │ │ -| }); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_TEST(rate_limit_accrue_limit) | │ │ │ │ │ -|{ | │ │ │ │ │ -| aux::session_settings sett; | │ │ │ │ │ -| sett.set_int(settings_pack::dht_upload_rate_limit, std::numeric_limits::max()); | │ │ │ │ │ -| | │ │ │ │ │ -| test_rate_limit(sett, [](lt::dht::socket_manager& sm) { | │ │ │ │ │ -| TEST_CHECK(sm.has_quota()); | │ │ │ │ │ -| for (int i = 0; i < 10; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::this_thread::sleep_for(milliseconds(500)); | │ │ │ │ │ -| TEST_CHECK(sm.has_quota()); | │ │ │ │ │ -| } | │ │ │ │ │ -| }); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|#else | │ │ │ │ │ -|TORRENT_TEST(dht) | │ │ │ │ │ -|{ | │ │ │ │ │ -| // dummy dht test | │ │ │ │ │ -| TEST_CHECK(true); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/ |test sending invalid requests (out of bound piece index, offsets and sizes) | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___f_a_s_t___e_x_t_e_n_s_i_o_n_._c_p_p_:_1_1_3_5_ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt sseennddiinngg iinnvvaalliidd rreeqquueessttss ((oouutt ooff bboouunndd ppiieeccee iinnddeexx,, ooffffsseettss aanndd ssiizzeess)) ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_aa_ss_tt____ee_xx_tt_ee_nn_ss_ii_oo_nn_.._cc_pp_pp_::_11_11_33_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/ |test files with different piece size (negative test) | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___r_e_s_o_l_v_e___l_i_n_k_s_._c_p_p_:_9_5_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteesstt ffiilleess wwiitthh ddiiffffeerreenntt ppiieeccee ssiizzee ((nneeggaattiivvee tteesstt)) ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__rreessoollvvee__lliinnkkss..ccpppp::9955 ****** | │ │ │ │ │ -|{ "test2", "test1_pad_files", 0}, | │ │ │ │ │ -| { "test3", "test1_pad_files", 0}, | │ │ │ │ │ -| { "test2", "test1_single", 0}, | │ │ │ │ │ -| | │ │ │ │ │ -| // these are all padded. The first small file will accidentally also | │ │ │ │ │ -| // match, even though it's not tail padded, the following file is identical | │ │ │ │ │ -| { "test2_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ -| { "test3_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ -| { "test3_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ -| { "test1_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ -| { "test1_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ -| { "test2_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ -| | │ │ │ │ │ -| // one might expect this to work, but since the tail of the single file | │ │ │ │ │ -| // torrent is not padded, the last piece hash won't match | │ │ │ │ │ -| { "test1_pad_files", "test1_single", 0}, | │ │ │ │ │ -| | │ │ │ │ │ -| // if it's padded on the other hand, it will work | │ │ │ │ │ -| { "test1_pad_files", "test1_single_padded", 1}, | │ │ │ │ │ -| | │ │ │ │ │ -|_}_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/ |it would be nice to test resolving of more than just 2 files as well. like 3 single file torrents merged into one, resolving all 3 | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___r_e_s_o_l_v_e___l_i_n_k_s_._c_p_p_:_9_8_ _ _ _ _ _|_f_i_l_e_s_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo tteesstt rreessoollvviinngg ooff mmoorree tthhaann jjuusstt 22 ffiilleess aass wweellll.. lliikkee 33 ssiinnggllee ffiillee ttoorrrreennttss mmeerrggeedd iinnttoo oonnee,, rreessoollvviinngg aallll 33 ffiilleess.. ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__rreessoollvvee__lliinnkkss..ccpppp::9988 ****** | │ │ │ │ │ -|{ "test2", "test1_single", 0}, | │ │ │ │ │ -| | │ │ │ │ │ -| // these are all padded. The first small file will accidentally also | │ │ │ │ │ -| // match, even though it's not tail padded, the following file is identical | │ │ │ │ │ -| { "test2_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ -| { "test3_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ -| { "test3_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ -| { "test1_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ -| { "test1_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ -| { "test2_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ -| | │ │ │ │ │ -| // one might expect this to work, but since the tail of the single file | │ │ │ │ │ -| // torrent is not padded, the last piece hash won't match | │ │ │ │ │ -| { "test1_pad_files", "test1_single", 0}, | │ │ │ │ │ -| | │ │ │ │ │ -| // if it's padded on the other hand, it will work | │ │ │ │ │ -| { "test1_pad_files", "test1_single_padded", 1}, | │ │ │ │ │ -| | │ │ │ │ │ -|}; | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_TEST(resolve_links) | │ │ │ │ │ -|{ | │ │ │ │ │ -| std::string path = combine_path(parent_path(current_working_directory()) | │ │ │ │ │ -| , "mutable_test_torrents"); | │ │ │ │ │ -| | │ │ │ │ │ -| for (int i = 0; i < int(sizeof(test_torrents)/sizeof(test_torrents[0])); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| test_torrent_t const& e = test_torrents[i]; | │ │ │ │ │ -| | │ │ │ │ │ -| std::string p = combine_path(path, e.filename1) + ".torrent"; | │ │ │ │ │ -| std::printf("loading %s\n", p.c_str()); | │ │ │ │ │ -| std::shared_ptr ti1 = std::make_shared(p); | │ │ │ │ │ -| | │ │ │ │ │ -| p = combine_path(path, e.filename2) + ".torrent"; | │ │ │ │ │ -| std::printf("loading %s\n", p.c_str()); | │ │ │ │ │ -| std::shared_ptr ti2 = std::make_shared(p); | │ │ │ │ │ -| | │ │ │ │ │ -| std::printf("resolving\n"); | │ │ │ │ │ -| resolve_links l(ti1); | │ │ │ │ │ -| l.match(ti2, "."); | │ │ │ │ │ -| | │ │ │ │ │ -| aux::vector const& links = l.get_links(); | │ │ │ │ │ -| | │ │ │ │ │ -| auto const num_matches = std::size_t(std::count_if(links.begin(), links.end() | │ │ │ │ │ -| , std::bind(&resolve_links::link_t::ti, _1))); | │ │ │ │ │ -| | │ │ │ │ │ -| // some debug output in case the test fails | │ │ │ │ │ -| if (num_matches > e.expected_matches) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _f_i_l_e___s_t_o_r_a_g_e_ _c_o_n_s_t_&_ _f_s_ _=_ _t_i_1_-_>_f_i_l_e_s_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___r_e_s_u_m_e_._c_p_p_:_5_8_2_ _ _ _|_t_e_s_t_ _w_h_a_t_ _h_a_p_p_e_n_s_ _w_h_e_n_ _l_o_a_d_i_n_g_ _a_ _r_e_s_u_m_e_ _f_i_l_e_ _w_i_t_h_ _b_o_t_h_ _p_i_e_c_e_ _p_r_i_o_r_i_t_i_e_s_ _a_n_d_ _f_i_l_e_ _p_r_i_o_r_i_t_i_e_s_ _(_f_i_l_e_ _p_r_i_o_ _s_h_o_u_l_d_ _t_a_k_e_ _p_r_e_c_e_d_e_n_c_e_)_ _ _ _ _ _ | │ │ │ │ │ |********** tteesstt wwhhaatt hhaappppeennss wwhheenn llooaaddiinngg aa rreessuummee ffiillee wwiitthh bbootthh ppiieeccee pprriioorriittiieess aanndd ffiillee pprriioorriittiieess ((ffiillee pprriioo sshhoouulldd ttaakkee pprreecceeddeennccee)) ********** | │ │ │ │ │ |****** ....//tteesstt//tteesstt__rreessuummee..ccpppp::558822 ****** | │ │ │ │ │ |{ | │ │ │ │ │ | TEST_EQUAL(pieces[i], true); | │ │ │ │ │ | } | │ │ │ │ │ | } | │ │ │ │ │ @@ -5904,393 +5585,920 @@ │ │ │ │ │ |template | │ │ │ │ │ |void test_unfinished_pieces(Fun f) | │ │ │ │ │ |{ | │ │ │ │ │ | // create a torrent and complete files | │ │ │ │ │ | std::shared_ptr ti = generate_torrent(true, true); | │ │ │ │ │ | | │ │ │ │ │ |_ _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_ _p_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_l_a_g_s_._c_p_p_:_1_6_3 |change to a different test setup. currently always paused. test_set_after_add(torrent_flags::paused); test_unset_after_add | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_(_t_o_r_r_e_n_t___f_l_a_g_s_:_:_p_a_u_s_e_d_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** cchhaannggee ttoo aa ddiiffffeerreenntt tteesstt sseettuupp.. ccuurrrreennttllyy aallwwaayyss ppaauusseedd.. tteesstt__sseett__aafftteerr__aadddd((ttoorrrreenntt__ffllaaggss::::ppaauusseedd));; tteesstt__uunnsseett__aafftteerr__aadddd((ttoorrrreenntt__ffllaaggss::::ppaauusseedd));; ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ffllaaggss..ccpppp::116633 ****** | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/ |test files with different piece size (negative test) | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___r_e_s_o_l_v_e___l_i_n_k_s_._c_p_p_:_9_5_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ffiilleess wwiitthh ddiiffffeerreenntt ppiieeccee ssiizzee ((nneeggaattiivvee tteesstt)) ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__rreessoollvvee__lliinnkkss..ccpppp::9955 ****** | │ │ │ │ │ +|{ "test2", "test1_pad_files", 0}, | │ │ │ │ │ +| { "test3", "test1_pad_files", 0}, | │ │ │ │ │ +| { "test2", "test1_single", 0}, | │ │ │ │ │ +| | │ │ │ │ │ +| // these are all padded. The first small file will accidentally also | │ │ │ │ │ +| // match, even though it's not tail padded, the following file is identical | │ │ │ │ │ +| { "test2_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ +| { "test3_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ +| { "test3_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ +| { "test1_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ +| { "test1_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ +| { "test2_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ +| | │ │ │ │ │ +| // one might expect this to work, but since the tail of the single file | │ │ │ │ │ +| // torrent is not padded, the last piece hash won't match | │ │ │ │ │ +| { "test1_pad_files", "test1_single", 0}, | │ │ │ │ │ +| | │ │ │ │ │ +| // if it's padded on the other hand, it will work | │ │ │ │ │ +| { "test1_pad_files", "test1_single_padded", 1}, | │ │ │ │ │ +| | │ │ │ │ │ +|_}_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/ |it would be nice to test resolving of more than just 2 files as well. like 3 single file torrents merged into one, resolving all 3 | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___r_e_s_o_l_v_e___l_i_n_k_s_._c_p_p_:_9_8_ _ _ _ _ _|_f_i_l_e_s_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo tteesstt rreessoollvviinngg ooff mmoorree tthhaann jjuusstt 22 ffiilleess aass wweellll.. lliikkee 33 ssiinnggllee ffiillee ttoorrrreennttss mmeerrggeedd iinnttoo oonnee,, rreessoollvviinngg aallll 33 ffiilleess.. ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__rreessoollvvee__lliinnkkss..ccpppp::9988 ****** | │ │ │ │ │ +|{ "test2", "test1_single", 0}, | │ │ │ │ │ +| | │ │ │ │ │ +| // these are all padded. The first small file will accidentally also | │ │ │ │ │ +| // match, even though it's not tail padded, the following file is identical | │ │ │ │ │ +| { "test2_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ +| { "test3_pad_files", "test1_pad_files", 2}, | │ │ │ │ │ +| { "test3_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ +| { "test1_pad_files", "test2_pad_files", 2}, | │ │ │ │ │ +| { "test1_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ +| { "test2_pad_files", "test3_pad_files", 2}, | │ │ │ │ │ +| | │ │ │ │ │ +| // one might expect this to work, but since the tail of the single file | │ │ │ │ │ +| // torrent is not padded, the last piece hash won't match | │ │ │ │ │ +| { "test1_pad_files", "test1_single", 0}, | │ │ │ │ │ +| | │ │ │ │ │ +| // if it's padded on the other hand, it will work | │ │ │ │ │ +| { "test1_pad_files", "test1_single_padded", 1}, | │ │ │ │ │ +| | │ │ │ │ │ +|}; | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(resolve_links) | │ │ │ │ │ |{ | │ │ │ │ │ -| // share-mode | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::share_mode); | │ │ │ │ │ -| test_set_after_add(torrent_flags::share_mode); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::share_mode); | │ │ │ │ │ -|} | │ │ │ │ │ -|#endif | │ │ │ │ │ +| std::string path = combine_path(parent_path(current_working_directory()) | │ │ │ │ │ +| , "mutable_test_torrents"); | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_apply_ip_filter) | │ │ │ │ │ +| for (int i = 0; i < int(sizeof(test_torrents)/sizeof(test_torrents[0])); ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| test_torrent_t const& e = test_torrents[i]; | │ │ │ │ │ +| | │ │ │ │ │ +| std::string p = combine_path(path, e.filename1) + ".torrent"; | │ │ │ │ │ +| std::printf("loading %s\n", p.c_str()); | │ │ │ │ │ +| std::shared_ptr ti1 = std::make_shared(p); | │ │ │ │ │ +| | │ │ │ │ │ +| p = combine_path(path, e.filename2) + ".torrent"; | │ │ │ │ │ +| std::printf("loading %s\n", p.c_str()); | │ │ │ │ │ +| std::shared_ptr ti2 = std::make_shared(p); | │ │ │ │ │ +| | │ │ │ │ │ +| std::printf("resolving\n"); | │ │ │ │ │ +| resolve_links l(ti1); | │ │ │ │ │ +| l.match(ti2, "."); | │ │ │ │ │ +| | │ │ │ │ │ +| aux::vector const& links = l.get_links(); | │ │ │ │ │ +| | │ │ │ │ │ +| auto const num_matches = std::size_t(std::count_if(links.begin(), links.end() | │ │ │ │ │ +| , std::bind(&resolve_links::link_t::ti, _1))); | │ │ │ │ │ +| | │ │ │ │ │ +| // some debug output in case the test fails | │ │ │ │ │ +| if (num_matches > e.expected_matches) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _f_i_l_e___s_t_o_r_a_g_e_ _c_o_n_s_t_&_ _f_s_ _=_ _t_i_1_-_>_f_i_l_e_s_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_0_ _ _ _|_t_e_s_t_ _s_c_r_a_p_e_ _r_e_q_u_e_s_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ssccrraappee rreeqquueessttss ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_00_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_1_ _ _ _|_t_e_s_t_ _p_a_r_s_e_ _p_e_e_r_s_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ppaarrssee ppeeeerrss66 ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_11_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_2_ _ _ _|_t_e_s_t_ _p_a_r_s_e_ _t_r_a_c_k_e_r_-_i_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ppaarrssee ttrraacckkeerr--iidd ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_22_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_3_ _ _ _|_t_e_s_t_ _p_a_r_s_e_ _f_a_i_l_u_r_e_-_r_e_a_s_o_n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ppaarrssee ffaaiilluurree--rreeaassoonn ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_rr_aa_cc_kk_ee_rr_.._cc_pp_pp_::_66_33_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_c_k_e_r_._c_p_p_:_6_4 |test all failure paths, including invalid bencoding not a dictionary no files entry in scrape response no info-hash entry in scrape | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_r_e_s_p_o_n_s_e_ _m_a_l_f_o_r_m_e_d_ _p_e_e_r_s_ _i_n_ _p_e_e_r_ _l_i_s_t_ _o_f_ _d_i_c_t_i_o_n_a_r_i_e_s_ _u_n_e_v_e_n_ _n_u_m_b_e_r_ _o_f_ _b_y_t_e_s_ _i_n_ _p_e_e_r_s_ _a_n_d_ _p_e_e_r_s_6_ _s_t_r_i_n_g_ _r_e_s_p_o_n_s_e_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt aallll ffaaiilluurree ppaatthhss,, iinncclluuddiinngg iinnvvaalliidd bbeennccooddiinngg nnoott aa ddiiccttiioonnaarryy nnoo ffiilleess eennttrryy iinn ssccrraappee rreessppoonnssee nnoo iinnffoo--hhaasshh eennttrryy iinn ssccrraappee rreessppoonnssee mmaallffoorrmmeedd ppeeeerrss iinn ppeeeerr lliisstt| │ │ │ │ │ +|ooff ddiiccttiioonnaarriieess uunneevveenn nnuummbbeerr ooff bbyytteess iinn ppeeeerrss aanndd ppeeeerrss66 ssttrriinngg rreessppoonnsseess ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ttrraacckkeerr..ccpppp::6644 ****** | │ │ │ │ │ +|#include "test_utils.hpp" | │ │ │ │ │ +|#include "udp_tracker.hpp" | │ │ │ │ │ +|#include "settings.hpp" | │ │ │ │ │ +|#include "test_utils.hpp" | │ │ │ │ │ +|#include "libtorrent/alert.hpp" | │ │ │ │ │ +|#include "libtorrent/peer_info.hpp" // for peer_list_entry | │ │ │ │ │ +|#include "libtorrent/alert_types.hpp" | │ │ │ │ │ +|#include "libtorrent/session.hpp" | │ │ │ │ │ +|#include "libtorrent/session_params.hpp" | │ │ │ │ │ +|#include "libtorrent/error_code.hpp" | │ │ │ │ │ +|#include "libtorrent/tracker_manager.hpp" | │ │ │ │ │ +|#include "libtorrent/http_tracker_connection.hpp" // for parse_tracker_response | │ │ │ │ │ +|#include "libtorrent/torrent_info.hpp" | │ │ │ │ │ +|#include "libtorrent/announce_entry.hpp" | │ │ │ │ │ +|#include "libtorrent/torrent.hpp" | │ │ │ │ │ +|#include "libtorrent/aux_/path.hpp" | │ │ │ │ │ +|#include "libtorrent/socket_io.hpp" | │ │ │ │ │ +| | │ │ │ │ │ +|using namespace lt; | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(parse_hostname_peers) | │ │ │ │ │ |{ | │ │ │ │ │ -| // apply-ip-filter | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::apply_ip_filter); | │ │ │ │ │ -| test_set_after_add(torrent_flags::apply_ip_filter); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::apply_ip_filter); | │ │ │ │ │ +| char const response[] = "d5:peersld7:peer id20:aaaaaaaaaaaaaaaaaaaa" | │ │ │ │ │ +| "2:ip13:test_hostname4:porti1000eed" | │ │ │ │ │ +| "7:peer id20:bbbbabaababababababa2:ip12:another_host4:porti1001eeee"; | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| tracker_response resp = parse_tracker_response(response | │ │ │ │ │ +| , ec, {}, sha1_hash()); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_EQUAL(ec, error_code()); | │ │ │ │ │ +| TEST_EQUAL(resp.peers.size(), 2); | │ │ │ │ │ +| if (resp.peers.size() == 2) | │ │ │ │ │ +| { | │ │ │ │ │ +| peer_entry const& e0 = resp.peers[0]; | │ │ │ │ │ +| peer_entry const& e1 = resp.peers[1]; | │ │ │ │ │ +| TEST_EQUAL(e0.hostname, "test_hostname"); | │ │ │ │ │ +| TEST_EQUAL(e0.port, 1000); | │ │ │ │ │ +| TEST_EQUAL(e0.pid, peer_id("aaaaaaaaaaaaaaaaaaaa")); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_EQUAL(e1.hostname, "another_host"); | │ │ │ │ │ +| TEST_EQUAL(e1.port, 1001); | │ │ │ │ │ +| TEST_EQUAL(e1.pid, peer_id("bbbbabaababababababa")); | │ │ │ │ │ +| } | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_paused) | │ │ │ │ │ +|TORRENT_TEST(parse_peers4) | │ │ │ │ │ |{ | │ │ │ │ │ -| // paused | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::paused); | │ │ │ │ │ +| char const response[] = "d5:peers12:\x01\x02\x03\x04\x30\x10" | │ │ │ │ │ +| "\x09\x08\x07\x06\x20\x10" "e"; | │ │ │ │ │ +|_ _e_r_r_o_r___c_o_d_e_ _e_c_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___u_p_n_p_._c_p_p_:_1_5_6_ _ _ _ _ _|_s_t_o_r_e_ _t_h_e_ _l_o_g_ _a_n_d_ _v_e_r_i_f_y_ _t_h_a_t_ _s_o_m_e_ _k_e_y_ _m_e_s_s_a_g_e_s_ _a_r_e_ _t_h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssttoorree tthhee lloogg aanndd vveerriiffyy tthhaatt ssoommee kkeeyy mmeessssaaggeess aarree tthheerree ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__uuppnnpp..ccpppp::115566 ****** | │ │ │ │ │ +|, portmap_protocol const protocol, error_code const& err | │ │ │ │ │ +| , portmap_transport, aux::listen_socket_handle const&) override | │ │ │ │ │ +| { | │ │ │ │ │ +| callback_info info = {mapping, port, err}; | │ │ │ │ │ +| callbacks.push_back(info); | │ │ │ │ │ +| std::cout << "mapping: " << static_cast(mapping) | │ │ │ │ │ +| << ", port: " << port << ", IP: " << ip | │ │ │ │ │ +| << ", proto: " << static_cast(protocol) | │ │ │ │ │ +| << ", error: \"" << err.message() << "\"\n"; | │ │ │ │ │ +| } | │ │ │ │ │ +| #ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| bool should_log_portmap(portmap_transport) const override | │ │ │ │ │ +| { | │ │ │ │ │ +| return true; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void log_portmap(portmap_transport, char const* msg | │ │ │ │ │ +| , aux::listen_socket_handle const&) const override | │ │ │ │ │ +| { | │ │ │ │ │ +| std::cout << "UPnP: " << msg << std::endl; | │ │ │ │ │ |} | │ │ │ │ │ +|#endif | │ │ │ │ │ +| }; | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_auto_managed) | │ │ │ │ │ +|ip_interface pick_upnp_interface() | │ │ │ │ │ |{ | │ │ │ │ │ -| // auto-managed | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::auto_managed); | │ │ │ │ │ -| test_set_after_add(torrent_flags::auto_managed); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::auto_managed); | │ │ │ │ │ +| lt::io_context ios; | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| std::vector const routes = enum_routes(ios, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::cerr << "failed to enumerate routes: " << ec.message() << '\n'; | │ │ │ │ │ +| TEST_CHECK(false); | │ │ │ │ │ +| return {}; | │ │ │ │ │ +| } | │ │ │ │ │ +| std::vector const ifs = enum_net_interfaces(ios, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::cerr << "failed to enumerate network interfaces: " << ec.message() << '\n'; | │ │ │ │ │ +| TEST_CHECK(false); | │ │ │ │ │ +| return {}; | │ │ │ │ │ +| } | │ │ │ │ │ +| int idx = 0; | │ │ │ │ │ +| for (auto const& face : ifs) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!face.interface_address.is_v4()) continue; | │ │ │ │ │ +| std::cout << " - " << idx | │ │ │ │ │ +| << ' ' << face.interface_address.to_string() | │ │ │ │ │ +| << ' ' << int(static_cast(face.state)) | │ │ │ │ │ +| << ' ' << static_cast(face.flags) | │ │ │ │ │ +|_ _ _ _<_<_ _'_ _'_ _<_<_ _f_a_c_e_._n_a_m_e_ _<_<_ _'_\_n_'_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___d_h_t_._c_p_p_:_4_7_2_ _ _ _ _ _ _|_c_h_e_c_k_ _t_o_ _m_a_k_e_ _s_u_r_e_ _t_h_e_ _"_b_e_s_t_"_ _i_t_e_m_s_ _a_r_e_ _s_t_o_r_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** cchheecckk ttoo mmaakkee ssuurree tthhee ""bbeesstt"" iitteemmss aarree ssttoorreedd ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ddhhtt..ccpppp::447722 ****** | │ │ │ │ │ +|, msg_args().target(items[j].target)); | │ │ │ │ │ +| | │ │ │ │ │ +| key_desc_t const desc[] = | │ │ │ │ │ +| { | │ │ │ │ │ +| { "r", bdecode_node::dict_t, 0, key_desc_t::parse_children }, | │ │ │ │ │ +| { "v", bdecode_node::dict_t, 0, 0}, | │ │ │ │ │ +| { "id", bdecode_node::string_t, 20, key_desc_t::last_child}, | │ │ │ │ │ +| { "y", bdecode_node::string_t, 1, 0}, | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| bdecode_node parsed[4]; | │ │ │ │ │ +| char error_string[200]; | │ │ │ │ │ +| | │ │ │ │ │ +| int ret = verify_message(response, desc, parsed, error_string); | │ │ │ │ │ +| if (ret) | │ │ │ │ │ +| { | │ │ │ │ │ +| items_num.insert(items_num.begin(), j); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|TEST_EQUAL(items_num.size(), 4); | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ -|// super seeding mode is automatically turned off if we're not a seed | │ │ │ │ │ -|// since the posix_disk_io is not threaded, this will happen immediately | │ │ │ │ │ -|#if TORRENT_HAVE_MMAP | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_SUPERSEEDING | │ │ │ │ │ -|TORRENT_TEST(flag_super_seeding) | │ │ │ │ │ +|int sum_distance_exp(int s, node_entry const& e, node_id const& ref) | │ │ │ │ │ |{ | │ │ │ │ │ -| // super-seeding | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::super_seeding); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::super_seeding); | │ │ │ │ │ -| test_set_after_add(torrent_flags::super_seeding); | │ │ │ │ │ +| return s + distance_exp(e.id, ref); | │ │ │ │ │ |} | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#endif | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_sequential_download) | │ │ │ │ │ +|std::vector g_got_peers; | │ │ │ │ │ +| | │ │ │ │ │ +|void get_peers_cb(std::vector const& peers) | │ │ │ │ │ |{ | │ │ │ │ │ -| // sequential-download | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::sequential_download); | │ │ │ │ │ -| test_set_after_add(torrent_flags::sequential_download); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::sequential_download); | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_l_a_g_s_._c_p_p_:_2_0_5 |this test is flaky, since the torrent will become ready before asking for the flags, and by then stop_when_ready will have been | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_c_l_e_a_r_e_d_ _t_e_s_t___a_d_d___a_n_d___g_e_t___f_l_a_g_s_(_t_o_r_r_e_n_t___f_l_a_g_s_:_:_s_t_o_p___w_h_e_n___r_e_a_d_y_)_;_ _s_e_t_t_i_n_g_ _s_t_o_p_-_w_h_e_n_-_r_e_a_d_y_ _w_h_e_n_ _a_l_r_e_a_d_y_ _s_t_o_p_p_e_d_ _h_a_s_ _n_o_ _e_f_f_e_c_t_._ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss tteesstt iiss ffllaakkyy,, ssiinnccee tthhee ttoorrrreenntt wwiillll bbeeccoommee rreeaaddyy bbeeffoorree aasskkiinngg ffoorr tthhee ffllaaggss,, aanndd bbyy tthheenn ssttoopp__wwhheenn__rreeaaddyy wwiillll hhaavvee bbeeeenn cclleeaarreedd tteesstt__aadddd__aanndd__ggeett__ffllaaggss | │ │ │ │ │ -|((ttoorrrreenntt__ffllaaggss::::ssttoopp__wwhheenn__rreeaaddyy));; sseettttiinngg ssttoopp--wwhheenn--rreeaaddyy wwhheenn aallrreeaaddyy ssttooppppeedd hhaass nnoo eeffffeecctt.. ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_ll_aa_gg_ss_.._cc_pp_pp_::_22_00_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___f_l_a_g_s_._c_p_p_:_2_0_9_ _ _ _ _|_c_h_a_n_g_e_ _t_o_ _a_ _d_i_f_f_e_r_e_n_t_ _t_e_s_t_ _s_e_t_u_p_._ _c_u_r_r_e_n_t_l_y_ _a_l_w_a_y_s_ _p_a_u_s_e_d_._ _t_e_s_t___s_e_t___a_f_t_e_r___a_d_d_(_t_o_r_r_e_n_t___f_l_a_g_s_:_:_s_t_o_p___w_h_e_n___r_e_a_d_y_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** cchhaannggee ttoo aa ddiiffffeerreenntt tteesstt sseettuupp.. ccuurrrreennttllyy aallwwaayyss ppaauusseedd.. tteesstt__sseett__aafftteerr__aadddd((ttoorrrreenntt__ffllaaggss::::ssttoopp__wwhheenn__rreeaaddyy));; ********** | │ │ │ │ │ -|****** ....//tteesstt//tteesstt__ffllaaggss..ccpppp::220099 ****** | │ │ │ │ │ -|test_set_after_add(torrent_flags::super_seeding); | │ │ │ │ │ +| g_got_peers.insert(g_got_peers.end(), peers.begin(), peers.end()); | │ │ │ │ │ |} | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#endif | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_sequential_download) | │ │ │ │ │ +|std::vector g_got_items; | │ │ │ │ │ +|dht::item g_put_item; | │ │ │ │ │ +|int g_put_count; | │ │ │ │ │ +| | │ │ │ │ │ +|void get_mutable_item_cb(dht::item const& i, bool a) | │ │ │ │ │ |{ | │ │ │ │ │ -| // sequential-download | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::sequential_download); | │ │ │ │ │ -| test_set_after_add(torrent_flags::sequential_download); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::sequential_download); | │ │ │ │ │ +| if (!a) return; | │ │ │ │ │ +| if (!i.empty()) | │ │ │ │ │ +| g_got_items.push_back(i); | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ -|// the stop when ready flag will be cleared when the torrent is ready to start | │ │ │ │ │ -|// downloading. | │ │ │ │ │ -|// since the posix_disk_io is not threaded, this will happen immediately | │ │ │ │ │ -|#if TORRENT_HAVE_MMAP | │ │ │ │ │ -|TORRENT_TEST(flag_stop_when_ready) | │ │ │ │ │ +|void put_mutable_item_data_cb(dht::item& i) | │ │ │ │ │ |{ | │ │ │ │ │ -| // stop-when-ready | │ │ │ │ │ -|test_unset_after_add(torrent_flags::stop_when_ready); | │ │ │ │ │ -|} | │ │ │ │ │ +| if (!i.empty()) | │ │ │ │ │ +|_ _ _g___g_o_t___i_t_e_m_s_._p_u_s_h___b_a_c_k_(_i_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___d_h_t_._c_p_p_:_3_2_2_3_ _ _ _ _ _|_t_h_i_s_ _w_o_n_'_t_ _w_o_r_k_ _b_e_c_a_u_s_e_ _t_h_e_ _s_e_c_o_n_d_ _n_o_d_e_ _i_s_n_'_t_ _p_i_n_g_e_d_ _s_o_ _i_t_ _w_o_n_t_ _b_e_ _a_d_d_e_d_ _t_o_ _t_h_e_ _r_o_u_t_i_n_g_ _t_a_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss wwoonn''tt wwoorrkk bbeeccaauussee tthhee sseeccoonndd nnooddee iissnn''tt ppiinnggeedd ssoo iitt wwoonntt bbee aaddddeedd ttoo tthhee rroouuttiinngg ttaabbllee ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ddhhtt..ccpppp::33222233 ****** | │ │ │ │ │ +|bool ret = verify_message(request, get_item_desc_ro, parsed, error_string); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_CHECK(ret); | │ │ │ │ │ +| TEST_EQUAL(parsed[3].int_value(), 1); | │ │ │ │ │ +| | │ │ │ │ │ +| // should have one node now, which is 4.4.4.4:1234 | │ │ │ │ │ +| TEST_EQUAL(std::get<0>(node.size()), 1); | │ │ │ │ │ +| // and no replacement nodes | │ │ │ │ │ +| TEST_EQUAL(std::get<1>(node.size()), 0); | │ │ │ │ │ +| | │ │ │ │ │ +| // now, disable read_only, try again. | │ │ │ │ │ +| g_sent_packets.clear(); | │ │ │ │ │ +| sett.set_bool(settings_pack::dht_read_only, false); | │ │ │ │ │ +| | │ │ │ │ │ +| send_dht_request(node, "get", source, &response); | │ │ │ │ │ +| // sender should be added to replacement bucket | │ │ │ │ │ +| TEST_EQUAL(std::get<1>(node.size()), 1); | │ │ │ │ │ +| | │ │ │ │ │ +| g_sent_packets.clear(); | │ │ │ │ │ +|#if 0 | │ │ │ │ │ +|target = generate_next(); | │ │ │ │ │ +|node.get_item(target, get_immutable_item_cb); | │ │ │ │ │ +| | │ │ │ │ │ +| // since we have 2 nodes, we should have two packets. | │ │ │ │ │ +| TEST_EQUAL(g_sent_packets.size(), 2); | │ │ │ │ │ +| | │ │ │ │ │ +| // both of them shouldn't have a 'ro' key. | │ │ │ │ │ +| node_from_entry(g_sent_packets.front().second, request); | │ │ │ │ │ +| ret = verify_message(request, get_item_desc_ro, parsed, error_string); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_CHECK(ret); | │ │ │ │ │ +| TEST_CHECK(!parsed[3]); | │ │ │ │ │ +| | │ │ │ │ │ +| node_from_entry(g_sent_packets.back().second, request); | │ │ │ │ │ +| ret = verify_message(request, get_item_desc_ro, parsed, error_string); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_CHECK(ret); | │ │ │ │ │ +| TEST_CHECK(!parsed[3]); | │ │ │ │ │ |#endif | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_disable_dht) | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +|// these tests rely on logging being enabled | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(invalid_error_msg) | │ │ │ │ │ +|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___d_h_t_._c_p_p_:_4_0_8_1_ _ _ _ _ _|_t_e_s_t_ _o_b_f_u_s_c_a_t_e_d___g_e_t___p_e_e_r_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt oobbffuussccaatteedd__ggeett__ppeeeerrss ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ddhhtt..ccpppp::44008811 ****** | │ │ │ │ │ +|TEST_CHECK(sm.has_quota()); | │ │ │ │ │ +| }); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(rate_limit_accrue_limit) | │ │ │ │ │ |{ | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::disable_dht); | │ │ │ │ │ -| test_set_after_add(torrent_flags::disable_dht); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::disable_dht); | │ │ │ │ │ +| aux::session_settings sett; | │ │ │ │ │ +| sett.set_int(settings_pack::dht_upload_rate_limit, std::numeric_limits::max()); | │ │ │ │ │ +| | │ │ │ │ │ +| test_rate_limit(sett, [](lt::dht::socket_manager& sm) { | │ │ │ │ │ +| TEST_CHECK(sm.has_quota()); | │ │ │ │ │ +| for (int i = 0; i < 10; ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::this_thread::sleep_for(milliseconds(500)); | │ │ │ │ │ +| TEST_CHECK(sm.has_quota()); | │ │ │ │ │ +| } | │ │ │ │ │ +| }); | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_disable_lsd) | │ │ │ │ │ +| | │ │ │ │ │ +|#else | │ │ │ │ │ +|TORRENT_TEST(dht) | │ │ │ │ │ |{ | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::disable_lsd); | │ │ │ │ │ -| test_set_after_add(torrent_flags::disable_lsd); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::disable_lsd); | │ │ │ │ │ +| // dummy dht test | │ │ │ │ │ +| TEST_CHECK(true); | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ -|TORRENT_TEST(flag_disable_pex) | │ │ │ │ │ +|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:|test file attributes | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_1_2_0_8_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ffiillee aattttrriibbuutteess ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_ii_ll_ee____ss_tt_oo_rr_aa_gg_ee_.._cc_pp_pp_::_11_22_00_88_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/_t_e_s_t___f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:|test symlinks | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_1_2_0_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt ssyymmlliinnkkss ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____ff_ii_ll_ee____ss_tt_oo_rr_aa_gg_ee_.._cc_pp_pp_::_11_22_00_99_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/ |test the case where we have > 120 samples (and have the base delay actually be updated) | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___t_i_m_e_s_t_a_m_p___h_i_s_t_o_r_y_._c_p_p_:_5_4_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt tthhee ccaassee wwhheerree wwee hhaavvee >> 112200 ssaammpplleess ((aanndd hhaavvee tthhee bbaassee ddeellaayy aaccttuuaallllyy bbee uuppddaatteedd)) ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_tt_ee_ss_tt_//_tt_ee_ss_tt____tt_ii_mm_ee_ss_tt_aa_mm_pp____hh_ii_ss_tt_oo_rr_yy_.._cc_pp_pp_::_55_44_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_t_e_s_t_/ |test the case where a sample is lower than the history entry but not lower than the base | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_t_e_s_t___t_i_m_e_s_t_a_m_p___h_i_s_t_o_r_y_._c_p_p_:_5_5_ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteesstt tthhee ccaassee wwhheerree aa ssaammppllee iiss lloowweerr tthhaann tthhee hhiissttoorryy eennttrryy bbuutt nnoott lloowweerr tthhaann tthhee bbaassee ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ttiimmeessttaammpp__hhiissttoorryy..ccpppp::5555 ****** | │ │ │ │ │ +|#include "libtorrent/aux_/timestamp_history.hpp" | │ │ │ │ │ +| | │ │ │ │ │ +|TORRENT_TEST(timestamp_history) | │ │ │ │ │ |{ | │ │ │ │ │ -| test_add_and_get_flags(torrent_flags::disable_pex); | │ │ │ │ │ -| test_set_after_add(torrent_flags::disable_pex); | │ │ │ │ │ -| test_unset_after_add(torrent_flags::disable_pex); | │ │ │ │ │ +| using namespace lt; | │ │ │ │ │ +| | │ │ │ │ │ +| aux::timestamp_history h; | │ │ │ │ │ +| TEST_EQUAL(h.add_sample(0x32, false), 0); | │ │ │ │ │ +| TEST_EQUAL(h.base(), 0x32); | │ │ │ │ │ +| TEST_EQUAL(h.add_sample(0x33, false), 0x1); | │ │ │ │ │ +| TEST_EQUAL(h.base(), 0x32); | │ │ │ │ │ +| TEST_EQUAL(h.add_sample(0x3433, false), 0x3401); | │ │ │ │ │ +| TEST_EQUAL(h.base(), 0x32); | │ │ │ │ │ +| TEST_EQUAL(h.add_sample(0x30, false), 0); | │ │ │ │ │ +| TEST_EQUAL(h.base(), 0x30); | │ │ │ │ │ +| | │ │ │ │ │ +| // test that wrapping of the timestamp is properly handled | │ │ │ │ │ +| h.add_sample(0xfffffff3, false); | │ │ │ │ │ +| TEST_EQUAL(h.base(), 0xfffffff3); | │ │ │ │ │ +| | │ │ │ │ │ |_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_a_c_k_e_t___b_u_f_f_e_r_._c_p_p_:_1_5_7_ _ _|_u_s_e_ _c_o_m_p_a_r_e___l_e_s_s___w_r_a_p_ _f_o_r_ _t_h_i_s_ _c_o_m_p_a_r_i_s_o_n_ _a_s_ _w_e_l_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee ccoommppaarree__lleessss__wwrraapp ffoorr tthhiiss ccoommppaarriissoonn aass wweellll ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppaacckkeett__bbuuffffeerr..ccpppp::115577 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| TORRENT_ASSERT_VAL(size <= 0xffff, size); | │ │ │ │ │ -| std::uint32_t new_size = m_capacity == 0 ? 16 : m_capacity; | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_t_e_s_t_/_t_e_s_t___t_r_a_n_s_f_e_r_._c_p_p_:_1_7_3_ _|_t_h_e_s_e_ _s_e_t_t_i_n_g_s___p_a_c_k_ _t_e_s_t_s_ _b_e_l_o_n_g_ _i_n_ _t_h_e_i_r_ _o_w_n_ _t_e_s_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthheessee sseettttiinnggss__ppaacckk tteessttss bbeelloonngg iinn tthheeiirr oowwnn tteesstt ********** | │ │ │ │ │ +|****** ....//tteesstt//tteesstt__ttrraannssffeerr..ccpppp::117733 ****** | │ │ │ │ │ +|// to the time it will take to complete the test | │ │ │ │ │ +| pack.set_int(settings_pack::min_reconnect_time, 0); | │ │ │ │ │ +| pack.set_int(settings_pack::stop_tracker_timeout, 1); | │ │ │ │ │ +| pack.set_bool(settings_pack::announce_to_all_trackers, true); | │ │ │ │ │ +| pack.set_bool(settings_pack::announce_to_all_tiers, true); | │ │ │ │ │ | | │ │ │ │ │ -| while (new_size < size) | │ │ │ │ │ -| new_size <<= 1; | │ │ │ │ │ +| // make sure we announce to both http and udp trackers | │ │ │ │ │ +| pack.set_bool(settings_pack::prefer_udp_trackers, false); | │ │ │ │ │ +| pack.set_bool(settings_pack::enable_outgoing_utp, false); | │ │ │ │ │ +| pack.set_bool(settings_pack::enable_incoming_utp, false); | │ │ │ │ │ +| pack.set_bool(settings_pack::enable_lsd, false); | │ │ │ │ │ +| pack.set_bool(settings_pack::enable_natpmp, false); | │ │ │ │ │ +| pack.set_bool(settings_pack::enable_upnp, false); | │ │ │ │ │ +| pack.set_bool(settings_pack::enable_dht, false); | │ │ │ │ │ | | │ │ │ │ │ -| aux::unique_ptr new_storage(new packet_ptr[new_size]); | │ │ │ │ │ +| pack.set_int(settings_pack::out_enc_policy, settings_pack::pe_disabled); | │ │ │ │ │ +| pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled); | │ │ │ │ │ | | │ │ │ │ │ -| for (index_type i = m_first; i < (m_first + m_capacity); ++i) | │ │ │ │ │ -| new_storage[i & (new_size - 1)] = std::move(m_storage[i & (m_capacity - 1)]); | │ │ │ │ │ +| pack.set_bool(settings_pack::allow_multiple_connections_per_ip, false); | │ │ │ │ │ | | │ │ │ │ │ -| m_storage = std::move(new_storage); | │ │ │ │ │ -| m_capacity = new_size; | │ │ │ │ │ -| } | │ │ │ │ │ +|pack.set_int(settings_pack::unchoke_slots_limit, 0); | │ │ │ │ │ +|ses1.apply_settings(pack); | │ │ │ │ │ +| TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == 0); | │ │ │ │ │ | | │ │ │ │ │ -| packet_ptr packet_buffer::remove(index_type idx) | │ │ │ │ │ -| { | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -|if (idx >= m_first + m_capacity) | │ │ │ │ │ -|return packet_ptr(); | │ │ │ │ │ +| pack.set_int(settings_pack::unchoke_slots_limit, -1); | │ │ │ │ │ +| ses1.apply_settings(pack); | │ │ │ │ │ +| TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == -1); | │ │ │ │ │ | | │ │ │ │ │ -| if (compare_less_wrap(idx, m_first, 0xffff)) | │ │ │ │ │ -| return packet_ptr(); | │ │ │ │ │ +| pack.set_int(settings_pack::unchoke_slots_limit, 8); | │ │ │ │ │ +| ses1.apply_settings(pack); | │ │ │ │ │ +| TEST_CHECK(ses1.get_settings().get_int(settings_pack::unchoke_slots_limit) == 8); | │ │ │ │ │ | | │ │ │ │ │ -| std::size_t const mask = m_capacity - 1; | │ │ │ │ │ -| packet_ptr old_value = std::move(m_storage[idx & mask]); | │ │ │ │ │ -| m_storage[idx & mask].reset(); | │ │ │ │ │ +| ses2.apply_settings(pack); | │ │ │ │ │ | | │ │ │ │ │ -| if (old_value) | │ │ │ │ │ +| torrent_handle tor1; | │ │ │ │ │ +| torrent_handle tor2; | │ │ │ │ │ +| | │ │ │ │ │ +| create_directory("tmp1_transfer", ec); | │ │ │ │ │ +| std::ofstream file("tmp1_transfer/temporary"); | │ │ │ │ │ +| std::shared_ptr t = ::create_torrent(&file, "temporary", 32 * 1024, 13, false); | │ │ │ │ │ +| file.close(); | │ │ │ │ │ +| | │ │ │ │ │ +| TEST_CHECK(exists(combine_path("tmp1_transfer", "temporary"))); | │ │ │ │ │ +| | │ │ │ │ │ +| add_torrent_params params; | │ │ │ │ │ +| params.storage_mode = storage_mode; | │ │ │ │ │ +| params.flags &= ~torrent_flags::paused; | │ │ │ │ │ +| params.flags &= ~torrent_flags::auto_managed; | │ │ │ │ │ +| | │ │ │ │ │ +| wait_for_listen(ses1, "ses1"); | │ │ │ │ │ +|_ _w_a_i_t___f_o_r___l_i_s_t_e_n_(_s_e_s_2_,_ _"_s_e_s_2_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_2_3_0 |ideally, if we end up copying files because of a move across volumes, the source should not be deleted until they've all been | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_c_o_p_i_e_d_._ _T_h_a_t_ _w_o_u_l_d_ _l_e_t_ _u_s_ _r_o_l_l_b_a_c_k_ _w_i_t_h_ _h_i_g_h_e_r_ _c_o_n_f_i_d_e_n_c_e_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iiddeeaallllyy,, iiff wwee eenndd uupp ccooppyyiinngg ffiilleess bbeeccaauussee ooff aa mmoovvee aaccrroossss vvoolluummeess,, tthhee ssoouurrccee sshhoouulldd nnoott bbee ddeelleetteedd uunnttiill tthheeyy''vvee aallll bbeeeenn ccooppiieedd.. TThhaatt wwoouulldd lleett uuss rroollllbbaacckk wwiitthh | │ │ │ │ │ +|hhiigghheerr ccoonnffiiddeennccee.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::223300 ****** | │ │ │ │ │ +|// later | │ │ │ │ │ +| aux::vector copied_files(std::size_t(f.num_files()), false); | │ │ │ │ │ +| | │ │ │ │ │ +| // track how far we got in case of an error | │ │ │ │ │ +| file_index_t file_index{}; | │ │ │ │ │ +| for (auto const i : f.file_range()) | │ │ │ │ │ | { | │ │ │ │ │ -| --m_size; | │ │ │ │ │ -| if (m_size == 0) m_last = m_first; | │ │ │ │ │ +| // files moved out to absolute paths are not moved | │ │ │ │ │ +| if (f.file_absolute_path(i)) continue; | │ │ │ │ │ +| | │ │ │ │ │ +| std::string const old_path = combine_path(save_path, f.file_path(i)); | │ │ │ │ │ +| std::string const new_path = combine_path(new_save_path, f.file_path(i)); | │ │ │ │ │ +| | │ │ │ │ │ +| error_code ignore; | │ │ │ │ │ +| if (flags == move_flags_t::dont_replace && exists(new_path, ignore)) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (ret == status_t::no_error) ret = status_t::need_full_check; | │ │ │ │ │ +| continue; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|move_file(old_path, new_path, ec); | │ │ │ │ │ +| | │ │ │ │ │ +| // if the source file doesn't exist. That's not a problem | │ │ │ │ │ +| // we just ignore that file | │ │ │ │ │ +| if (ec.ec == boost::system::errc::no_such_file_or_directory) | │ │ │ │ │ +| ec.ec.clear(); | │ │ │ │ │ +| else if (ec | │ │ │ │ │ +| && ec.ec != boost::system::errc::invalid_argument | │ │ │ │ │ +| && ec.ec != boost::system::errc::permission_denied) | │ │ │ │ │ +| { | │ │ │ │ │ +| // moving the file failed | │ │ │ │ │ +| // on OSX, the error when trying to rename a file across different | │ │ │ │ │ +| // volumes is EXDEV, which will make it fall back to copying. | │ │ │ │ │ +| ec.ec.clear(); | │ │ │ │ │ +| copy_file(old_path, new_path, ec); | │ │ │ │ │ +| if (!ec) copied_files[i] = true; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| ec.file(i); | │ │ │ │ │ +| file_index = i; | │ │ │ │ │ +| break; | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (idx == m_first && m_size != 0) | │ │ │ │ │ +| if (!ec && move_partfile) | │ │ │ │ │ | { | │ │ │ │ │ -| ++m_first; | │ │ │ │ │ -| for (index_type i = 0; i < m_capacity; ++i, ++m_first) | │ │ │ │ │ -| if (m_storage[m_first & mask]) break; | │ │ │ │ │ -| m_first &= 0xffff; | │ │ │ │ │ +| error_code e; | │ │ │ │ │ +| move_partfile(new_save_path, e); | │ │ │ │ │ +|_ _ _ _i_f_ _(_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_5_3_8 |it would seem reasonable to, instead, set the have_pieces bits for the pieces representing these files, and resume with the normal | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_l_o_g_i_c_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd sseeeemm rreeaassoonnaabbllee ttoo,, iinnsstteeaadd,, sseett tthhee hhaavvee__ppiieecceess bbiittss ffoorr tthhee ppiieecceess rreepprreesseennttiinngg tthheessee ffiilleess,, aanndd rreessuummee wwiitthh tthhee nnoorrmmaall llooggiicc ********** | │ │ │ │ │ +|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::553388 ****** | │ │ │ │ │ +|continue; | │ │ │ │ │ +| | │ │ │ │ │ +| std::int64_t const size = get_filesize(stat, file_index, fs | │ │ │ │ │ +| , save_path, ec); | │ │ │ │ │ +| if (size < 0) return false; | │ │ │ │ │ +| | │ │ │ │ │ +| if (size < fs.file_size(file_index)) | │ │ │ │ │ +| { | │ │ │ │ │ +| ec.ec = errors::mismatching_file_size; | │ │ │ │ │ +| ec.file(file_index); | │ │ │ │ │ +| ec.operation = operation_t::check_resume; | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| return true; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (((idx + 1) & 0xffff) == m_last && m_size != 0) | │ │ │ │ │ -| { | │ │ │ │ │ -| --m_last; | │ │ │ │ │ -| for (index_type i = 0; i < m_capacity; ++i, --m_last) | │ │ │ │ │ -| if (m_storage[m_last & mask]) break; | │ │ │ │ │ -| ++m_last; | │ │ │ │ │ -|_ _ _ _m___l_a_s_t_ _&_=_ _0_x_f_f_f_f_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___h_a_n_d_l_e_._c_p_p_:_4_9_9_ _|_i_n_ _C_+_+_1_4_,_ _u_s_e_ _u_n_i_q_u_e___p_t_r_ _a_n_d_ _m_o_v_e_ _i_t_ _i_n_t_o_ _t_h_e_ _l_a_m_b_d_a_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinn CC++++1144,, uussee uunniiqquuee__ppttrr aanndd mmoovvee iitt iinnttoo tthhee llaammbbddaa ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__hhaannddllee..ccpppp::449999 ****** | │ │ │ │ │ -|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ -| if (params.save_path.empty()) | │ │ │ │ │ -| aux::throw_ex(error_code(errors::invalid_save_path)); | │ │ │ │ │ -|#else | │ │ │ │ │ -| TORRENT_ASSERT_PRECOND(!params.save_path.empty()); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ +| // always trigger a full recheck when we pull in files from other | │ │ │ │ │ +| // torrents, via hard links | │ │ │ │ │ +|if (added_files) return false; | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_ABI_VERSION < 3 | │ │ │ │ │ -| if (!params.info_hashes.has_v1() && !params.info_hashes.has_v2() && !params.ti) | │ │ │ │ │ -| params.info_hashes.v1 = params.info_hash; | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // parse have bitmask. Verify that the files we expect to have | │ │ │ │ │ +| // actually do exist | │ │ │ │ │ +| piece_index_t const end_piece = std::min(rd.have_pieces.end_index(), fs.end_piece()); | │ │ │ │ │ +| for (piece_index_t i(0); i < end_piece; ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (rd.have_pieces.get_bit(i) == false) continue; | │ │ │ │ │ | | │ │ │ │ │ -| // the internal torrent object keeps and mutates state in the | │ │ │ │ │ -| // torrent_info object. We can't let that leak back to the client | │ │ │ │ │ -| if (params.ti) | │ │ │ │ │ -| params.ti = std::make_shared(*params.ti); | │ │ │ │ │ +| std::vector f = fs.map_block(i, 0, 1); | │ │ │ │ │ +| TORRENT_ASSERT(!f.empty()); | │ │ │ │ │ | | │ │ │ │ │ -| // we cannot capture a unique_ptr into a lambda in c++11, so we use a raw | │ │ │ │ │ -| // pointer for now. async_call uses a lambda expression to post the call | │ │ │ │ │ -| // to the main thread | │ │ │ │ │ -|auto* p = new add_torrent_params(std::move(params)); | │ │ │ │ │ -|auto guard = aux::scope_end([p]{ delete p; }); | │ │ │ │ │ -| p->save_path = complete(p->save_path); | │ │ │ │ │ +| file_index_t const file_index = f[0].file_index; | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| handle_backwards_compatible_resume_data(*p); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // files with priority zero may not have been saved to disk at their | │ │ │ │ │ +| // expected location, but is likely to be in a partfile. Just exempt it | │ │ │ │ │ +| // from checking | │ │ │ │ │ +| if (file_index < file_priority.end_index() | │ │ │ │ │ +| && file_priority[file_index] == dont_download) | │ │ │ │ │ +| continue; | │ │ │ │ │ | | │ │ │ │ │ -| async_call(&session_impl::async_add_torrent, p); | │ │ │ │ │ -| guard.disarm(); | │ │ │ │ │ -| } | │ │ │ │ │ +| if (fs.pad_file_at(file_index)) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| // if the torrent already exists, this will throw duplicate_torrent | │ │ │ │ │ -| torrent_handle session_handle::add_torrent( | │ │ │ │ │ -| torrent_info const& ti | │ │ │ │ │ -| , std::string const& save_path | │ │ │ │ │ -| , entry const& resume_data | │ │ │ │ │ -| , storage_mode_t storage_mode | │ │ │ │ │ -| , bool const add_paused) | │ │ │ │ │ -| { | │ │ │ │ │ -| add_torrent_params p; | │ │ │ │ │ -| p.ti = std::make_shared(ti); | │ │ │ │ │ -| p.save_path = save_path; | │ │ │ │ │ -| if (resume_data.type() != entry::undefined_t) | │ │ │ │ │ -| { | │ │ │ │ │ -| bencode(std::back_inserter(p.resume_data), resume_data); | │ │ │ │ │ +| if (get_filesize(stat, file_index, fs, save_path, ec) < 0) | │ │ │ │ │ +| return false; | │ │ │ │ │ +| | │ │ │ │ │ +| // OK, this file existed, good. Now, skip all remaining pieces in | │ │ │ │ │ +| // this file. We're just sanity-checking whether the files exist | │ │ │ │ │ +| // or not. | │ │ │ │ │ +|_ _ _ _p_e_e_r___r_e_q_u_e_s_t_ _c_o_n_s_t_ _p_r_ _=_ _f_s_._m_a_p___f_i_l_e_(_f_i_l_e___i_n_d_e_x_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_r_a_n_d_o_m_._c_p_p_:_1_4_1_ _ _ _ _ _ _ _ _ _|_i_m_p_r_o_v_e_ _c_a_l_l_i_n_g_ _R_A_N_D___b_y_t_e_s_ _m_u_l_t_i_p_l_e_ _t_i_m_e_s_,_ _u_s_i_n_g_ _f_a_l_l_b_a_c_k_ _f_o_r_ _n_o_w_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iimmpprroovvee ccaalllliinngg RRAANNDD__bbyytteess mmuullttiippllee ttiimmeess,, uussiinngg ffaallllbbaacckk ffoorr nnooww ********** | │ │ │ │ │ +|****** ....//ssrrcc//rraannddoomm..ccpppp::114411 ****** | │ │ │ │ │ +|#else | │ │ │ │ │ +| std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); | │ │ │ │ │ +|#endif | │ │ │ │ │ | } | │ │ │ │ │ -| p.storage_mode = storage_mode; | │ │ │ │ │ -|_ _ _i_f_ _(_a_d_d___p_a_u_s_e_d_)_ _p_._f_l_a_g_s_ _|_=_ _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_:_:_f_l_a_g___p_a_u_s_e_d_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_p_o_s_i_x___p_a_r_t___f_i_l_e_._c_p_p_:_3_3_7|what do we do if someone is currently reading from the disk from this piece? does it matter? Since we won't actively erase the data | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_f_r_o_m_ _d_i_s_k_,_ _b_u_t_ _i_t_ _m_a_y_ _b_e_ _o_v_e_r_w_r_i_t_t_e_n_ _s_o_o_n_,_ _i_t_'_s_ _p_r_o_b_a_b_l_y_ _n_o_t_ _t_h_a_t_ _b_i_g_ _o_f_ _a_ _d_e_a_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** wwhhaatt ddoo wwee ddoo iiff ssoommeeoonnee iiss ccuurrrreennttllyy rreeaaddiinngg ffrroomm tthhee ddiisskk ffrroomm tthhiiss ppiieeccee?? ddooeess iitt mmaatttteerr?? SSiinnccee wwee wwoonn''tt aaccttiivveellyy eerraassee tthhee ddaattaa ffrroomm ddiisskk,, bbuutt iitt mmaayy bbee oovveerrwwrriitttteenn | │ │ │ │ │ -|ssoooonn,, iitt''ss pprroobbaabbllyy nnoott tthhaatt bbiigg ooff aa ddeeaall ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppoossiixx__ppaarrtt__ffiillee..ccpppp::333377 ****** | │ │ │ │ │ -| if (ec) return {}; | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_WINDOWS | │ │ │ │ │ -| ret = file_pointer(::_wfopen(convert_to_native_path_string(fn).c_str(), L"wb+")); | │ │ │ │ │ +| void crypto_random_bytes(span buffer) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_BUILD_SIMULATOR | │ │ │ │ │ +| // In the simulator we want deterministic random numbers | │ │ │ │ │ +| std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); | │ │ │ │ │ +|#elif TORRENT_USE_CNG | │ │ │ │ │ +| aux::cng_gen_random(buffer); | │ │ │ │ │ +|#elif TORRENT_USE_CRYPTOAPI | │ │ │ │ │ +| // windows | │ │ │ │ │ +| aux::crypt_gen_random(buffer); | │ │ │ │ │ +|#elif defined TORRENT_USE_LIBCRYPTO && !defined TORRENT_USE_WOLFSSL | │ │ │ │ │ +|// wolfSSL uses wc_RNG_GenerateBlock as the internal function for the | │ │ │ │ │ +|// openssl compatibility layer. This function API does not support | │ │ │ │ │ +|// an arbitrary buffer size (openssl does), it is limited by the | │ │ │ │ │ +|// constant RNG_MAX_BLOCK_LEN. | │ │ │ │ │ +| | │ │ │ │ │ +|// openssl | │ │ │ │ │ +| int r = RAND_bytes(reinterpret_cast(buffer.data()) | │ │ │ │ │ +| , int(buffer.size())); | │ │ │ │ │ +| if (r != 1) aux::throw_ex(errors::no_entropy); | │ │ │ │ │ +|#elif TORRENT_USE_GETRANDOM | │ │ │ │ │ +| ssize_t const r = ::getrandom(buffer.data(), static_cast(buffer.size()), 0); | │ │ │ │ │ +| if (r == ssize_t(buffer.size())) return; | │ │ │ │ │ +| if (r == -1 && errno != ENOSYS) aux::throw_ex(error_code(errno, generic_category())); | │ │ │ │ │ +| static dev_random dev; | │ │ │ │ │ +| dev.read(buffer); | │ │ │ │ │ +|#elif TORRENT_USE_DEV_RANDOM | │ │ │ │ │ +| static dev_random dev; | │ │ │ │ │ +| dev.read(buffer); | │ │ │ │ │ |#else | │ │ │ │ │ -| ret = file_pointer(::fopen(fn.c_str(), "wb+")); | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_BROKEN_RANDOM_DEVICE | │ │ │ │ │ +| // even pseudo random numbers rely on being able to seed the random | │ │ │ │ │ +| // generator | │ │ │ │ │ +|#error "no entropy source available" | │ │ │ │ │ +|#else | │ │ │ │ │ +|#ifdef TORRENT_I_WANT_INSECURE_RANDOM_NUMBERS | │ │ │ │ │ +| std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); | │ │ │ │ │ +|#else | │ │ │ │ │ +|#error "no secure entropy source available. If you really want insecure random numbers, define TORRENT_I_WANT_INSECURE_RANDOM_NUMBERS" | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ |#endif | │ │ │ │ │ -| if (ret.file() == nullptr) | │ │ │ │ │ -| ec.assign(errno, generic_category()); | │ │ │ │ │ | } | │ │ │ │ │ -| if (ec) return {}; | │ │ │ │ │ -| return ret; | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_0_4_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _f_i_e_l_d_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhiiss ffiieelldd iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::440044 ****** | │ │ │ │ │ +| return torrent_alert::message() + ": state changed to: " | │ │ │ │ │ +| + state_str[state]; | │ │ │ │ │ +|#endif | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void posix_part_file::free_piece(piece_index_t const piece) | │ │ │ │ │ -| { | │ │ │ │ │ -| auto const i = m_piece_map.find(piece); | │ │ │ │ │ -| if (i == m_piece_map.end()) return; | │ │ │ │ │ -| | │ │ │ │ │ +| tracker_error_alert::tracker_error_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep, int times | │ │ │ │ │ +| , protocol_version v, string_view u, operation_t const operation | │ │ │ │ │ +| , error_code const& e | │ │ │ │ │ +| , string_view m) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , times_in_row(times) | │ │ │ │ │ +| , error(e) | │ │ │ │ │ +| , op(operation) | │ │ │ │ │ +| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| , status_code(e && e.category() == http_category() ? e.value() : -1) | │ │ │ │ │ +| , msg(m) | │ │ │ │ │ +|#endif | │ │ │ │ │ +|, version(v) | │ │ │ │ │ +|{ | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|m_free_slots.push_back(i->second); | │ │ │ │ │ -| m_piece_map.erase(i); | │ │ │ │ │ -| m_dirty_metadata = true; | │ │ │ │ │ +| char const* tracker_error_alert::failure_reason() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void posix_part_file::move_partfile(std::string const& path, error_code& ec) | │ │ │ │ │ +| std::string tracker_error_alert::message() const | │ │ │ │ │ | { | │ │ │ │ │ -| flush_metadata_impl(ec); | │ │ │ │ │ -| if (ec) return; | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char ret[400]; | │ │ │ │ │ +| std::snprintf(ret, sizeof(ret), "%s %s %s \"%s\" (%d)" | │ │ │ │ │ +| , tracker_alert::message().c_str() | │ │ │ │ │ +| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ +| , convert_from_native(error.message()).c_str(), error_message() | │ │ │ │ │ +| , times_in_row); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (!m_piece_map.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::string old_path = combine_path(m_path, m_name); | │ │ │ │ │ -| std::string new_path = combine_path(path, m_name); | │ │ │ │ │ +| tracker_warning_alert::tracker_warning_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , string_view u, protocol_version v, string_view m) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ +|_#_i_f_ _T_O_R_R_E_N_T___A_B_I___V_E_R_S_I_O_N_ _=_=_ _1_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_3_8_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhiiss iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::443388 ****** | │ │ │ │ │ +|return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char ret[400]; | │ │ │ │ │ +| std::snprintf(ret, sizeof(ret), "%s %s %s \"%s\" (%d)" | │ │ │ │ │ +| , tracker_alert::message().c_str() | │ │ │ │ │ +| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ +| , convert_from_native(error.message()).c_str(), error_message() | │ │ │ │ │ +| , times_in_row); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| rename(old_path, new_path, ec); | │ │ │ │ │ -| if (ec == boost::system::errc::no_such_file_or_directory) | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ +| tracker_warning_alert::tracker_warning_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , string_view u, protocol_version v, string_view m) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| , msg(m) | │ │ │ │ │ +|#endif | │ │ │ │ │ +|, version(v) | │ │ │ │ │ +|{ | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| storage_error se; | │ │ │ │ │ -| aux::copy_file(old_path, new_path, se); | │ │ │ │ │ -| ec = se.ec; | │ │ │ │ │ -| if (ec) return; | │ │ │ │ │ -| remove(old_path, ec); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| m_path = path; | │ │ │ │ │ -|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_o_s_i_x___p_a_r_t___f_i_l_e_._c_p_p_:_4_2_4_|_i_n_s_t_e_a_d_ _o_f_ _r_e_b_u_i_l_d_i_n_g_ _t_h_e_ _w_h_o_l_e_ _f_i_l_e_ _h_e_a_d_e_r_ _a_n_d_ _f_l_u_s_h_i_n_g_ _i_t_,_ _u_p_d_a_t_e_ _t_h_e_ _s_l_o_t_ _e_n_t_r_i_e_s_ _a_s_ _w_e_ _g_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinnsstteeaadd ooff rreebbuuiillddiinngg tthhee wwhhoollee ffiillee hheeaaddeerr aanndd fflluusshhiinngg iitt,, uuppddaattee tthhee sslloott eennttrriieess aass wwee ggoo ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppoossiixx__ppaarrtt__ffiillee..ccpppp::442244 ****** | │ │ │ │ │ -|} | │ │ │ │ │ -| auto bytes_read = std::fread(buf.get(), 1, std::size_t(block_to_copy), file.file()); | │ │ │ │ │ -| if (int(bytes_read) != block_to_copy) | │ │ │ │ │ -| ec.assign(errno, generic_category()); | │ │ │ │ │ +| char const* tracker_warning_alert::warning_message() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (ec) return; | │ │ │ │ │ +| std::string tracker_warning_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| return tracker_alert::message() + (version == protocol_version::V1 ? " v1" : " v2") + " warning: " + warning_message(); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| f(file_offset, {buf.get(), block_to_copy}); | │ │ │ │ │ -| } | │ │ │ │ │ -| file_offset += block_to_copy; | │ │ │ │ │ -| piece_offset = 0; | │ │ │ │ │ -| size -= block_to_copy; | │ │ │ │ │ -| } | │ │ │ │ │ +| scrape_reply_alert::scrape_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , int incomp, int comp, string_view u, protocol_version const v) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , incomplete(incomp) | │ │ │ │ │ +|_ _ _,_ _c_o_m_p_l_e_t_e_(_c_o_m_p_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_6_4_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhiiss iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::446644 ****** | │ │ │ │ │ +|char const* tracker_warning_alert::warning_message() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void posix_part_file::flush_metadata(error_code& ec) | │ │ │ │ │ +| std::string tracker_warning_alert::message() const | │ │ │ │ │ | { | │ │ │ │ │ -| flush_metadata_impl(ec); | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| return tracker_alert::message() + (version == protocol_version::V1 ? " v1" : " v2") + " warning: " + warning_message(); | │ │ │ │ │ +|#endif | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|void posix_part_file::flush_metadata_impl(error_code& ec) | │ │ │ │ │ +| scrape_reply_alert::scrape_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , int incomp, int comp, string_view u, protocol_version const v) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , incomplete(incomp) | │ │ │ │ │ +| , complete(comp) | │ │ │ │ │ +|, version(v) | │ │ │ │ │ |{ | │ │ │ │ │ -| // do we need to flush the metadata? | │ │ │ │ │ -| if (m_dirty_metadata == false) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_piece_map.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| // if we don't have any pieces left in the | │ │ │ │ │ -| // part file, remove it | │ │ │ │ │ -| std::string const p = combine_path(m_path, m_name); | │ │ │ │ │ -| remove(p, ec); | │ │ │ │ │ -| | │ │ │ │ │ -| if (ec == boost::system::errc::no_such_file_or_directory) | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| auto f = open_file(open_mode::read_write, ec); | │ │ │ │ │ -| if (ec) return; | │ │ │ │ │ +| std::string scrape_reply_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char ret[400]; | │ │ │ │ │ +| std::snprintf(ret, sizeof(ret), "%s %s scrape reply: %d %d" | │ │ │ │ │ +| , tracker_alert::message().c_str() | │ │ │ │ │ +| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ +| , incomplete, complete); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| std::vector header(static_cast(m_header_size)); | │ │ │ │ │ +| scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , string_view u, protocol_version const v, error_code const& e) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , error(e) | │ │ │ │ │ +| , m_msg_idx() | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| , msg(convert_from_native(e.message())) | │ │ │ │ │ +|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_9_3_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhiiss iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::449933 ****** | │ │ │ │ │ +|return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char ret[400]; | │ │ │ │ │ +| std::snprintf(ret, sizeof(ret), "%s %s scrape reply: %d %d" | │ │ │ │ │ +| , tracker_alert::message().c_str() | │ │ │ │ │ +| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ +| , incomplete, complete); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| using namespace libtorrent::aux; | │ │ │ │ │ +| scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , string_view u, protocol_version const v, error_code const& e) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , error(e) | │ │ │ │ │ +| , m_msg_idx() | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| , msg(convert_from_native(e.message())) | │ │ │ │ │ +|#endif | │ │ │ │ │ +|, version(v) | │ │ │ │ │ +|{ | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| char* ptr = header.data(); | │ │ │ │ │ -| write_uint32(m_max_pieces, ptr); | │ │ │ │ │ -| write_uint32(m_piece_size, ptr); | │ │ │ │ │ +| scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , string_view u, string_view m) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , error(errors::tracker_failure) | │ │ │ │ │ +| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| , msg(m) | │ │ │ │ │ +|#endif | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| for (piece_index_t piece(0); piece < piece_index_t(m_max_pieces); ++piece) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _a_u_t_o_ _c_o_n_s_t_ _i_ _=_ _m___p_i_e_c_e___m_a_p_._f_i_n_d_(_p_i_e_c_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_u_d_p___s_o_c_k_e_t_._c_p_p_:_6_5_9_ _ _ _ _ _|_p_e_r_h_a_p_s_ _a_n_ _a_t_t_e_m_p_t_ _s_h_o_u_l_d_ _b_e_ _m_a_d_e_ _t_o_ _b_i_n_d_ _m___s_o_c_k_s_5___s_o_c_k_ _t_o_ _t_h_e_ _d_e_v_i_c_e_ _o_f_ _m___l_i_s_t_e_n___s_o_c_k_e_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ppeerrhhaappss aann aatttteemmpptt sshhoouulldd bbee mmaaddee ttoo bbiinndd mm__ssoocckkss55__ssoocckk ttoo tthhee ddeevviiccee ooff mm__lliisstteenn__ssoocckkeett ********** | │ │ │ │ │ -|****** ....//ssrrcc//uuddpp__ssoocckkeett..ccpppp::665599 ****** | │ │ │ │ │ -|if (ec) | │ │ │ │ │ +| char const* scrape_failed_alert::error_message() const | │ │ │ │ │ | { | │ │ │ │ │ -| if (m_alerts.should_post()) | │ │ │ │ │ -| m_alerts.emplace_alert(m_proxy_addr, operation_t::sock_option, ec); | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ +| if (m_msg_idx == aux::allocation_slot()) return ""; | │ │ │ │ │ +| else return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ | } | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#endif | │ │ │ │ │ | | │ │ │ │ │ -| tcp::endpoint const bind_ep(m_listen_socket.get_local_endpoint().address(), 0); | │ │ │ │ │ -| m_socks5_sock.bind(bind_ep, ec); | │ │ │ │ │ -| if (ec) | │ │ │ │ │ +| std::string scrape_failed_alert::message() const | │ │ │ │ │ | { | │ │ │ │ │ -| if (m_alerts.should_post()) | │ │ │ │ │ -| m_alerts.emplace_alert(m_proxy_addr, operation_t::sock_bind, ec); | │ │ │ │ │ -| ++m_failures; | │ │ │ │ │ -| retry_connection(); | │ │ │ │ │ -| return; | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| return tracker_alert::message() + " scrape failed: " + error_message(); | │ │ │ │ │ +|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_5_3_2_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _f_i_e_l_d_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhiiss ffiieelldd iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::553322 ****** | │ │ │ │ │ +|char const* scrape_failed_alert::error_message() const | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_msg_idx == aux::allocation_slot()) return ""; | │ │ │ │ │ +| else return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ +| std::string scrape_failed_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| return tracker_alert::message() + " scrape failed: " + error_message(); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|ADD_OUTSTANDING_ASYNC("socks5::on_connected"); | │ │ │ │ │ -| m_socks5_sock.async_connect(m_proxy_addr | │ │ │ │ │ -| , std::bind(&socks5::on_connected, self(), _1)); | │ │ │ │ │ +| tracker_reply_alert::tracker_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ +| , int np, protocol_version v, string_view u) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , num_peers(np) | │ │ │ │ │ +|, version(v) | │ │ │ │ │ +|{ | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| ADD_OUTSTANDING_ASYNC("socks5::on_connect_timeout"); | │ │ │ │ │ -| m_timer.expires_after(seconds(10)); | │ │ │ │ │ -| m_timer.async_wait(std::bind(&socks5::on_connect_timeout | │ │ │ │ │ -| , self(), _1)); | │ │ │ │ │ -|} | │ │ │ │ │ +| std::string tracker_reply_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char ret[400]; | │ │ │ │ │ +| std::snprintf(ret, sizeof(ret), "%s %s received peers: %d" | │ │ │ │ │ +| , tracker_alert::message().c_str() | │ │ │ │ │ +| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ +| , num_peers); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|void socks5::on_connect_timeout(error_code const& e) | │ │ │ │ │ -|{ | │ │ │ │ │ -| COMPLETE_ASYNC("socks5::on_connect_timeout"); | │ │ │ │ │ +| dht_reply_alert::dht_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h | │ │ │ │ │ +| , int np) | │ │ │ │ │ +| : tracker_alert(alloc, h, {}, "") | │ │ │ │ │ +| , num_peers(np) | │ │ │ │ │ +| {} | │ │ │ │ │ | | │ │ │ │ │ -| if (e == boost::asio::error::operation_aborted) return; | │ │ │ │ │ +| std::string dht_reply_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|_#_e_l_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_5_7_6_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhiiss ttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//aalleerrtt..ccpppp::557766 ****** | │ │ │ │ │ +|, num_peers(np) | │ │ │ │ │ +| {} | │ │ │ │ │ | | │ │ │ │ │ -| if (m_abort) return; | │ │ │ │ │ +| std::string dht_reply_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| char ret[400]; | │ │ │ │ │ +| std::snprintf(ret, sizeof(ret), "%s received DHT peers: %d" | │ │ │ │ │ +| , tracker_alert::message().c_str(), num_peers); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (m_alerts.should_post()) | │ │ │ │ │ -| m_alerts.emplace_alert(m_proxy_addr, operation_t::connect, errors::timed_out); | │ │ │ │ │ +| tracker_announce_alert::tracker_announce_alert(aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h, tcp::endpoint const& ep, string_view u | │ │ │ │ │ +| , protocol_version const v, event_t const e) | │ │ │ │ │ +| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ +| , event(e) | │ │ │ │ │ +|, version(v) | │ │ │ │ │ +|{ | │ │ │ │ │ +| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| error_code ignore; | │ │ │ │ │ -| m_socks5_sock.close(ignore); | │ │ │ │ │ +| std::string tracker_announce_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +| return {}; | │ │ │ │ │ +|#else | │ │ │ │ │ +| static const char* const event_str[] = {"none", "completed", "started", "stopped", "paused"}; | │ │ │ │ │ +| return tracker_alert::message() | │ │ │ │ │ +| + (version == protocol_version::V1 ? " v1" : " v2") | │ │ │ │ │ +| + " sending announce (" + event_str[static_cast(event)] + ")"; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| ++m_failures; | │ │ │ │ │ -| retry_connection(); | │ │ │ │ │ -|} | │ │ │ │ │ +| hash_failed_alert::hash_failed_alert( | │ │ │ │ │ +| aux::stack_allocator& alloc | │ │ │ │ │ +| , torrent_handle const& h | │ │ │ │ │ +| , piece_index_t index) | │ │ │ │ │ +| : torrent_alert(alloc, h) | │ │ │ │ │ +| , piece_index(index) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(index >= piece_index_t(0)); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|void socks5::on_connected(error_code const& e) | │ │ │ │ │ -|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| std::string hash_failed_alert::message() const | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ +|_ _ _r_e_t_u_r_n_ _{_}_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_e_n_u_m___n_e_t_._c_p_p_:_1_4_4_ _ _ _ _ _ _ _|_i_n_ _C_+_+_1_7_,_ _u_s_e_ _____h_a_s___i_n_c_l_u_d_e_ _f_o_r_ _t_h_i_s_._ _O_t_h_e_r_ _o_p_e_r_a_t_i_n_g_ _s_y_s_t_e_m_s_ _a_r_e_ _l_i_k_e_l_y_ _t_o_ _r_e_q_u_i_r_e_ _t_h_i_s_ _a_s_ _w_e_l_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** iinn CC++++1177,, uussee ____hhaass__iinncclluuddee ffoorr tthhiiss.. OOtthheerr ooppeerraattiinngg ssyysstteemmss aarree lliikkeellyy ttoo rreeqquuiirree tthhiiss aass wweellll ********** | │ │ │ │ │ |****** ....//ssrrcc//eennuumm__nneett..ccpppp::114444 ****** | │ │ │ │ │ |#include | │ │ │ │ │ |#include | │ │ │ │ │ |#include | │ │ │ │ │ |#include | │ │ │ │ │ @@ -6472,880 +6680,1708 @@ │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ | if (!m_pc.packet_finished()) return true; | │ │ │ │ │ | | │ │ │ │ │ | error_code ec; | │ │ │ │ │ | bdecode_node msg = bdecode(body, ec); | │ │ │ │ │ |_ _ _ _i_f_ _(_m_s_g_._t_y_p_e_(_)_ _!_=_ _b_d_e_c_o_d_e___n_o_d_e_:_:_d_i_c_t___t_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_i_p___n_o_t_i_f_i_e_r_._c_p_p_:_4_1_ _ _ _ _ _|_s_i_m_u_l_a_t_o_r_ _s_u_p_p_o_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssiimmuullaattoorr ssuuppppoorrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//iipp__nnoottiiffiieerr..ccpppp::4411 ****** | │ │ │ │ │ -| from this software without specific prior written permission. | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_9_5_1_ _ _ _ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _o_p_t_i_m_i_z_e_d_ _b_y_ _l_o_o_k_i_n_g_ _u_p_ _w_h_i_c_h_ _f_i_l_e_s_ _a_r_e_ _c_o_m_p_l_e_t_e_ _a_n_d_ _j_u_s_t_ _l_o_o_k_ _a_t_ _t_h_o_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ccoouulldd bbee ooppttiimmiizzeedd bbyy llooookkiinngg uupp wwhhiicchh ffiilleess aarree ccoommpplleettee aanndd jjuusstt llooookk aatt tthhoossee ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11995511 ****** | │ │ │ │ │ +|// TORRENT_ASSERT(picker().have_piece(i)); | │ │ │ │ │ +| we_have(i); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | │ │ │ │ │ -|AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | │ │ │ │ │ -|IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | │ │ │ │ │ -|ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | │ │ │ │ │ -|LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | │ │ │ │ │ -|CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | │ │ │ │ │ -|SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | │ │ │ │ │ -|INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | │ │ │ │ │ -|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ -|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ -|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ +| set_state(torrent_status::checking_resume_data); | │ │ │ │ │ | | │ │ │ │ │ -|*/ | │ │ │ │ │ +| aux::vector links; | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ +| if (!m_torrent_file->similar_torrents().empty() | │ │ │ │ │ +| || !m_torrent_file->collections().empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| resolve_links res(m_torrent_file); | │ │ │ │ │ | | │ │ │ │ │ -|#include "libtorrent/aux_/ip_notifier.hpp" | │ │ │ │ │ -|#include "libtorrent/assert.hpp" | │ │ │ │ │ +| for (auto const& ih : m_torrent_file->similar_torrents()) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::shared_ptr t = m_ses.find_torrent(info_hash_t(ih)).lock(); | │ │ │ │ │ +| if (!t) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#if defined TORRENT_BUILD_SIMULATOR | │ │ │ │ │ -|#elif TORRENT_USE_NETLINK | │ │ │ │ │ -|#include "libtorrent/netlink.hpp" | │ │ │ │ │ -|#include "libtorrent/socket.hpp" | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -|#elif TORRENT_USE_SYSTEMCONFIGURATION || TORRENT_USE_SC_NETWORK_REACHABILITY | │ │ │ │ │ -|#include | │ │ │ │ │ -|#elif defined TORRENT_WINDOWS | │ │ │ │ │ -|#include "libtorrent/aux_/throw.hpp" | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ -|#include | │ │ │ │ │ -|#ifdef TORRENT_WINRT | │ │ │ │ │ -|#include | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // Only attempt to reuse files from torrents that are seeding. | │ │ │ │ │ +|if (!t->is_seed()) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#include "libtorrent/aux_/netlink_utils.hpp" | │ │ │ │ │ +| res.match(t->get_torrent_file(), t->save_path()); | │ │ │ │ │ +| } | │ │ │ │ │ +| for (auto const& c : m_torrent_file->collections()) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::vector> ts = m_ses.find_collection(c); | │ │ │ │ │ | | │ │ │ │ │ -|namespace libtorrent { namespace aux { | │ │ │ │ │ +| for (auto const& t : ts) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _ _ _/_/_ _O_n_l_y_ _a_t_t_e_m_p_t_ _t_o_ _r_e_u_s_e_ _f_i_l_e_s_ _f_r_o_m_ _t_o_r_r_e_n_t_s_ _t_h_a_t_ _a_r_e_ _s_e_e_d_i_n_g_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_9_6_4_ _ _ _ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _o_p_t_i_m_i_z_e_d_ _b_y_ _l_o_o_k_i_n_g_ _u_p_ _w_h_i_c_h_ _f_i_l_e_s_ _a_r_e_ _c_o_m_p_l_e_t_e_ _a_n_d_ _j_u_s_t_ _l_o_o_k_ _a_t_ _t_h_o_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ccoouulldd bbee ooppttiimmiizzeedd bbyy llooookkiinngg uupp wwhhiicchh ffiilleess aarree ccoommpplleettee aanndd jjuusstt llooookk aatt tthhoossee ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11996644 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| resolve_links res(m_torrent_file); | │ │ │ │ │ | | │ │ │ │ │ -|namespace { | │ │ │ │ │ +| for (auto const& ih : m_torrent_file->similar_torrents()) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::shared_ptr t = m_ses.find_torrent(info_hash_t(ih)).lock(); | │ │ │ │ │ +| if (!t) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#if (TORRENT_USE_SYSTEMCONFIGURATION || TORRENT_USE_SC_NETWORK_REACHABILITY) && \ | │ │ │ │ │ -| !defined TORRENT_BUILD_SIMULATOR | │ │ │ │ │ +| // Only attempt to reuse files from torrents that are seeding. | │ │ │ │ │ +| if (!t->is_seed()) continue; | │ │ │ │ │ | | │ │ │ │ │ -|// common utilities for Mac and iOS | │ │ │ │ │ -|template void CFRefRetain(T h) { CFRetain(h); } | │ │ │ │ │ -|_t_e_m_p_l_a_t_e_ _<_t_y_p_e_n_a_m_e_ _T_>_ _v_o_i_d_ _C_F_R_e_f_R_e_l_e_a_s_e_(_T_ _h_)_ _{_ _C_F_R_e_l_e_a_s_e_(_h_)_;_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/ |technically, this isn't supposed to happen, but it seems to sometimes. Some of the accounting is probably wrong in certain cases | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_h_t_t_p___s_e_e_d___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_4_4_1_ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tteecchhnniiccaallllyy,, tthhiiss iissnn''tt ssuuppppoosseedd ttoo hhaappppeenn,, bbuutt iitt sseeeemmss ttoo ssoommeettiimmeess.. SSoommee ooff tthhee aaccccoouunnttiinngg iiss pprroobbaabbllyy wwrroonngg iinn cceerrttaaiinn ccaasseess ********** | │ │ │ │ │ -|****** ....//ssrrcc//hhttttpp__sseeeedd__ccoonnnneeccttiioonn..ccpppp::444411 ****** | │ │ │ │ │ -|// cut out the chunk header from the receive buffer | │ │ │ │ │ -| TORRENT_ASSERT(m_chunk_pos + m_body_start < INT_MAX); | │ │ │ │ │ -| m_recv_buffer.cut(header_size, t->block_size() + 1024, aux::numeric_cast(m_chunk_pos + m_body_start)); | │ │ │ │ │ -| recv_buffer = m_recv_buffer.get(); | │ │ │ │ │ -| recv_buffer = recv_buffer.subspan(m_body_start); | │ │ │ │ │ -| m_chunk_pos += chunk_size; | │ │ │ │ │ -| if (chunk_size == 0) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(m_recv_buffer.get().size() < m_chunk_pos + m_body_start + 1 | │ │ │ │ │ -| || m_recv_buffer.get()[static_cast(m_chunk_pos + m_body_start)] == 'H' | │ │ │ │ │ -| || (m_parser.chunked_encoding() | │ │ │ │ │ -| && m_recv_buffer.get()[static_cast(m_chunk_pos + m_body_start)] == '\r')); | │ │ │ │ │ -| m_chunk_pos = -1; | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ +| res.match(t->get_torrent_file(), t->save_path()); | │ │ │ │ │ | } | │ │ │ │ │ +| for (auto const& c : m_torrent_file->collections()) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::vector> ts = m_ses.find_collection(c); | │ │ │ │ │ | | │ │ │ │ │ -| int payload = int(bytes_transferred); | │ │ │ │ │ -| if (payload > m_response_left) payload = int(m_response_left); | │ │ │ │ │ -| if (payload > front_request.length) payload = front_request.length; | │ │ │ │ │ -|if (payload > outstanding_bytes()) payload = outstanding_bytes(); | │ │ │ │ │ -|received_bytes(payload, 0); | │ │ │ │ │ -| incoming_piece_fragment(payload); | │ │ │ │ │ -| m_response_left -= payload; | │ │ │ │ │ +| for (auto const& t : ts) | │ │ │ │ │ +| { | │ │ │ │ │ +| // Only attempt to reuse files from torrents that are seeding. | │ │ │ │ │ +|if (!t->is_seed()) continue; | │ │ │ │ │ | | │ │ │ │ │ -| if (m_parser.status_code() == 503) | │ │ │ │ │ +| res.match(t->get_torrent_file(), t->save_path()); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| std::vector const& l = res.get_links(); | │ │ │ │ │ +| if (!l.empty()) | │ │ │ │ │ | { | │ │ │ │ │ -| if (!m_parser.finished()) return; | │ │ │ │ │ +| links.resize(m_torrent_file->files().num_files()); | │ │ │ │ │ +| for (auto const& i : l) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (!i.ti) continue; | │ │ │ │ │ +| links[i.file_idx] = combine_path(i.save_path | │ │ │ │ │ +| , i.ti->files().file_path(i.file_idx)); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif // TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ | | │ │ │ │ │ -| int retry_time = std::atoi(std::string(recv_buffer.begin(), recv_buffer.end()).c_str()); | │ │ │ │ │ -| if (retry_time <= 0) retry_time = 60; | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| peer_log(peer_log_alert::info, "CONNECT", "retrying in %d seconds", retry_time); | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| TORRENT_ASSERT(m_outstanding_check_files == false); | │ │ │ │ │ +| m_outstanding_check_files = true; | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| received_bytes(0, int(bytes_transferred)); | │ │ │ │ │ -| // temporarily unavailable, retry later | │ │ │ │ │ -| t->retry_web_seed(this, seconds32(retry_time)); | │ │ │ │ │ -| disconnect(error_code(m_parser.status_code(), http_category()), operation_t::bittorrent, failure); | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ +| if (!m_add_torrent_params || !(m_add_torrent_params->flags & torrent_flags::no_verify_files)) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_ses.disk_thread().async_check_files( | │ │ │ │ │ +| m_storage, m_add_torrent_params ? m_add_torrent_params.get() : nullptr | │ │ │ │ │ +| , std::move(links), [self = shared_from_this()](status_t st, storage_error const& error) | │ │ │ │ │ +|_ _ _ _ _{_ _s_e_l_f_-_>_o_n___r_e_s_u_m_e___d_a_t_a___c_h_e_c_k_e_d_(_s_t_,_ _e_r_r_o_r_)_;_ _}_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_2_7_2_8 |this pattern is repeated in a few places. Factor this into a function and generalize the concept of a torrent having a dedicated | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_l_i_s_t_e_n_ _p_o_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ppaatttteerrnn iiss rreeppeeaatteedd iinn aa ffeeww ppllaacceess.. FFaaccttoorr tthhiiss iinnttoo aa ffuunnccttiioonn aanndd ggeenneerraalliizzee tthhee ccoonncceepptt ooff aa ttoorrrreenntt hhaavviinngg aa ddeeddiiccaatteedd lliisstteenn ppoorrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::22772288 ****** | │ │ │ │ │ +|// not ready for peers. Except, if we don't have metadata, | │ │ │ │ │ +| // we need peers to download from | │ │ │ │ │ +| if (!m_files_checked && valid_metadata()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| if (!m_announce_to_lsd) return; | │ │ │ │ │ | | │ │ │ │ │ +| // private torrents are never announced on LSD | │ │ │ │ │ +| if (m_torrent_file->is_valid() && m_torrent_file->priv()) return; | │ │ │ │ │ | | │ │ │ │ │ -| // we only received the header, no data | │ │ │ │ │ -| if (recv_buffer.empty()) break; | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| // i2p torrents are also never announced on LSD | │ │ │ │ │ +| // unless we allow mixed swarms | │ │ │ │ │ +| if (is_i2p() && !settings().get_bool(settings_pack::allow_i2p_mixed)) | │ │ │ │ │ +| return; | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| if (recv_buffer.size() < front_request.length) break; | │ │ │ │ │ +| if (is_paused()) return; | │ │ │ │ │ | | │ │ │ │ │ -| // if the response is chunked, we need to receive the last | │ │ │ │ │ -| // terminating chunk and the tail headers before we can proceed | │ │ │ │ │ -|_ _ _ _i_f_ _(_m___p_a_r_s_e_r_._c_h_u_n_k_e_d___e_n_c_o_d_i_n_g_(_)_ _&_&_ _m___c_h_u_n_k___p_o_s_ _>_=_ _0_)_ _b_r_e_a_k_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_6_1_5_ _ _ _|_c_o_m_e_ _u_p_ _w_i_t_h_ _s_o_m_e_ _a_b_s_t_r_a_c_t_i_o_n_ _t_o_ _d_o_ _t_h_i_s_ _f_o_r_ _g_n_u_t_l_s_ _a_s_ _w_e_l_l_ _l_o_a_d_ _c_e_r_t_i_f_i_c_a_t_e_s_ _f_r_o_m_ _t_h_e_ _w_i_n_d_o_w_s_ _s_y_s_t_e_m_ _c_e_r_t_i_f_i_c_a_t_e_ _s_t_o_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ccoommee uupp wwiitthh ssoommee aabbssttrraaccttiioonn ttoo ddoo tthhiiss ffoorr ggnnuuttllss aass wweellll llooaadd cceerrttiiffiiccaatteess ffrroomm tthhee wwiinnddoowwss ssyysstteemm cceerrttiiffiiccaattee ssttoorree ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::661155 ****** | │ │ │ │ │ -|pause(); | │ │ │ │ │ -| } | │ │ │ │ │ +| if (!m_ses.has_lsd()) return; | │ │ │ │ │ +| | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +|int port = is_ssl_torrent() ? m_ses.ssl_listen_port() : m_ses.listen_port(); | │ │ │ │ │ +|#else | │ │ │ │ │ +| int port = m_ses.listen_port(); | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| // This function is called by the creating thread, not in the message loop's | │ │ │ │ │ -| // io_context thread. | │ │ │ │ │ -| void session_impl::start_session() | │ │ │ │ │ +| // announce with the local discovery service | │ │ │ │ │ +| m_torrent_file->info_hashes().for_each([&](sha1_hash const& ih, protocol_version) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_ses.announce_lsd(ih, port); | │ │ │ │ │ +| }); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| | │ │ │ │ │ +| void torrent::dht_announce() | │ │ │ │ │ | { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| if (!m_ses.dht()) | │ │ │ │ │ +| { | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| session_log("start session"); | │ │ │ │ │ +| debug_log("DHT: no dht initialized"); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ +| if (!should_announce_dht()) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| { | │ │ │ │ │ +|_#_i_f_ _T_O_R_R_E_N_T___U_S_E___I_2_P_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_3_8_8_5_ _ _ _ _ _ _ _|_a_d_d_ _o_n_e_ _p_e_e_r_ _p_e_r_ _I_P_ _t_h_e_ _h_o_s_t_n_a_m_e_ _r_e_s_o_l_v_e_s_ _t_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aadddd oonnee ppeeeerr ppeerr IIPP tthhee hhoossttnnaammee rreessoollvveess ttoo ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::33888855 ****** | │ │ │ │ │ +|catch (...) { handle_exception(); } | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_SSL | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| m_ssl_ctx.set_default_verify_paths(ec); | │ │ │ │ │ +| void torrent::on_peer_name_lookup(error_code const& e | │ │ │ │ │ +| , std::vector
    const& host_list, int const port | │ │ │ │ │ +| , protocol_version const v) try | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| | │ │ │ │ │ +| COMPLETE_ASYNC("torrent::on_peer_name_lookup"); | │ │ │ │ │ +| | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (ec) session_log("SSL set_default verify_paths failed: %s", ec.message().c_str()); | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ +| if (e && should_log()) | │ │ │ │ │ +| debug_log("peer name lookup error: %s", e.message().c_str()); | │ │ │ │ │ |#endif | │ │ │ │ │ -|#if defined TORRENT_WINDOWS && defined TORRENT_USE_OPENSSL && !defined TORRENT_WINRT | │ │ │ │ │ -|X509_STORE* store = X509_STORE_new(); | │ │ │ │ │ -|if (store) | │ │ │ │ │ +| | │ │ │ │ │ +| if (e || m_abort || host_list.empty() || m_ses.is_aborted()) return; | │ │ │ │ │ +| | │ │ │ │ │ +|tcp::endpoint host(host_list.front(), std::uint16_t(port)); | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_ip_filter && m_ip_filter->access(host.address()) & ip_filter::blocked) | │ │ │ │ │ | { | │ │ │ │ │ -| HCERTSTORE system_store = CertOpenSystemStoreA(0, "ROOT"); | │ │ │ │ │ -| // this is best effort | │ │ │ │ │ -| if (system_store) | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ | { | │ │ │ │ │ -| CERT_CONTEXT const* ctx = nullptr; | │ │ │ │ │ -| while ((ctx = CertEnumCertificatesInStore(system_store, ctx)) != nullptr) | │ │ │ │ │ -| { | │ │ │ │ │ -| unsigned char const* cert_ptr = reinterpret_cast(ctx->pbCertEncoded); | │ │ │ │ │ -| X509* x509 = d2i_X509(nullptr, &cert_ptr, ctx->cbCertEncoded); | │ │ │ │ │ -| // this is best effort | │ │ │ │ │ -| if (!x509) continue; | │ │ │ │ │ -| X509_STORE_add_cert(store, x509); | │ │ │ │ │ -| X509_free(x509); | │ │ │ │ │ -| } | │ │ │ │ │ -| CertFreeCertificateContext(ctx); | │ │ │ │ │ -| CertCloseStore(system_store, 0); | │ │ │ │ │ +| debug_log("blocked ip from tracker: %s", host.address().to_string().c_str()); | │ │ │ │ │ | } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| if (m_ses.alerts().should_post()) | │ │ │ │ │ +| m_ses.alerts().emplace_alert(get_handle() | │ │ │ │ │ +| , host, peer_blocked_alert::ip_filter); | │ │ │ │ │ +| return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| SSL_CTX* ssl_ctx = m_ssl_ctx.native_handle(); | │ │ │ │ │ -| SSL_CTX_set_cert_store(ssl_ctx, store); | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#ifdef __APPLE__ | │ │ │ │ │ -| m_ssl_ctx.load_verify_file("/etc/ssl/cert.pem", ec); | │ │ │ │ │ +| if (add_peer(host, peer_info::tracker, v == protocol_version::V2 ? pex_lt_v2 : pex_flags_t(0))) | │ │ │ │ │ +| { | │ │ │ │ │ +| state_updated(); | │ │ │ │ │ +| | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (ec) session_log("SSL load_verify_file failed: %s", ec.message().c_str()); | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_1_4_8_4_ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _r_e_s_e_r_v_e_(_)_ _t_h_e_s_e_ _v_e_c_t_o_r_s_ _u_p_ _f_r_o_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo rreesseerrvvee(()) tthheessee vveeccttoorrss uupp ffrroonntt ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::11448844 ****** | │ │ │ │ │ -|bandwidth_channel* ch = &p->channel[peer_connection::download_channel]; | │ │ │ │ │ -| if (use_quota_overhead(ch, amount_down)) | │ │ │ │ │ -| ret |= 1 << peer_connection::download_channel; | │ │ │ │ │ -| ch = &p->channel[peer_connection::upload_channel]; | │ │ │ │ │ -| if (use_quota_overhead(ch, amount_up)) | │ │ │ │ │ -| ret |= 1 << peer_connection::upload_channel; | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| { | │ │ │ │ │ +| debug_log("name-lookup add_peer() [ %s ] connect-candidates: %d" | │ │ │ │ │ +| , host.address().to_string().c_str() | │ │ │ │ │ +| , m_peer_list ? m_peer_list->num_connect_candidates() : -1); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ | } | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ +| update_want_peers(); | │ │ │ │ │ +|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_5_8_1_ _ _ _ _ _ _ _|_o_n_l_y_ _d_o_ _t_h_i_s_ _i_f_ _t_h_e_ _p_i_e_c_e_ _s_i_z_e_ _>_ _1_ _b_l_o_c_k_s_ _T_h_i_s_ _i_s_ _a_ _v_2_ _t_o_r_r_e_n_t_ _s_o_ _w_e_ _c_a_n_ _r_e_q_u_e_s_t_ _g_e_t_ _b_l_o_c_k_ _l_e_v_e_l_ _h_a_s_h_e_s_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** oonnllyy ddoo tthhiiss iiff tthhee ppiieeccee ssiizzee >> 11 bblloocckkss TThhiiss iiss aa vv22 ttoorrrreenntt ssoo wwee ccaann rreeqquueesstt ggeett bblloocckk lleevveell hhaasshheess.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44558811 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| std::set ret; | │ │ │ │ │ +| if (!blocks.empty() && !downloaders.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| for (auto const b : blocks) ret.insert(downloaders[std::size_t(b)]); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| std::copy(downloaders.begin(), downloaders.end(), std::inserter(ret, ret.begin())); | │ │ │ │ │ +| } | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| }(); | │ │ │ │ │ | | │ │ │ │ │ -| // session_impl is responsible for deleting 'pack' | │ │ │ │ │ -| void session_impl::apply_settings_pack(std::shared_ptr pack) | │ │ │ │ │ -| { | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| apply_settings_pack_impl(*pack); | │ │ │ │ │ -| } | │ │ │ │ │ +| // if this piece wasn't downloaded from peers, we just found it on disk. | │ │ │ │ │ +| // In that case, we should just consider it as "not-have" and there's no | │ │ │ │ │ +| // need to try to get higher fidelity hashes (yet) | │ │ │ │ │ +| bool const found_on_disk = peers.size() == 1 && peers.count(nullptr); | │ │ │ │ │ | | │ │ │ │ │ -| settings_pack session_impl::get_settings() const | │ │ │ │ │ -| { | │ │ │ │ │ -| settings_pack ret; | │ │ │ │ │ -|for (int i = settings_pack::string_type_base; | │ │ │ │ │ -|i < settings_pack::max_string_setting_internal; ++i) | │ │ │ │ │ +| if (!torrent_file().info_hashes().has_v1() && blocks.empty() && !found_on_disk) | │ │ │ │ │ | { | │ │ │ │ │ -| ret.set_str(i, m_settings.get_str(i)); | │ │ │ │ │ +|verify_block_hashes(index); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| // the below code is penalizing peers that sent use bad data. | │ │ │ │ │ +| // increase the total amount of failed bytes | │ │ │ │ │ +| if (!found_on_disk) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (blocks.empty()) | │ │ │ │ │ +| add_failed_bytes(m_torrent_file->piece_size(index)); | │ │ │ │ │ +| else | │ │ │ │ │ +| add_failed_bytes(static_cast(blocks.size()) * default_block_size); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ +| for (auto& ext : m_extensions) | │ │ │ │ │ +| { | │ │ │ │ │ +| ext->on_piece_failed(index); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // did we receive this piece from a single peer? | │ │ │ │ │ +| // if we know exactly which blocks failed the hash, we can also be certain | │ │ │ │ │ +| // that all peers in the list sent us bad data | │ │ │ │ │ +| bool const known_bad_peer = (!found_on_disk && peers.size() == 1) || !blocks.empty(); | │ │ │ │ │ +| | │ │ │ │ │ +| penalize_peers(peers, index, known_bad_peer); | │ │ │ │ │ | } | │ │ │ │ │ -| for (int i = settings_pack::int_type_base; | │ │ │ │ │ -| i < settings_pack::max_int_setting_internal; ++i) | │ │ │ │ │ +| | │ │ │ │ │ +| // If m_storage isn't set here, it means we're shutting down | │ │ │ │ │ +| if (m_storage) | │ │ │ │ │ | { | │ │ │ │ │ -| ret.set_int(i, m_settings.get_int(i)); | │ │ │ │ │ +|_ _ _ _/_/_ _i_t_ _d_o_e_s_n_'_t_ _m_a_k_e_ _m_u_c_h_ _s_e_n_s_e_ _t_o_ _f_a_i_l_ _t_o_ _h_a_s_h_ _a_ _p_i_e_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_7_5_2_5_ _ _ _ _ _ _ _|_c_o_m_e_ _u_p_ _w_i_t_h_ _a_ _b_e_t_t_e_r_ _w_a_y_ _o_f_ _d_o_i_n_g_ _t_h_i_s_,_ _i_n_s_t_e_a_d_ _o_f_ _a_n_ _i_m_m_e_d_i_a_t_e_l_y_ _i_n_v_o_k_e_d_ _l_a_m_b_d_a_ _e_x_p_r_e_s_s_i_o_n_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ccoommee uupp wwiitthh aa bbeetttteerr wwaayy ooff ddooiinngg tthhiiss,, iinnsstteeaadd ooff aann iimmmmeeddiiaatteellyy iinnvvookkeedd llaammbbddaa eexxpprreessssiioonn.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::77552255 ****** | │ │ │ │ │ +||| peerinfo->confirmed_supports_utp)) | │ │ │ │ │ +| { | │ │ │ │ │ +| sm = m_ses.utp_socket_manager(); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // don't make a TCP connection if it's disabled | │ │ │ │ │ +| if (sm == nullptr && !settings().get_bool(settings_pack::enable_outgoing_tcp)) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ +| { | │ │ │ │ │ +| debug_log("discarding peer \"%s\": TCP connections disabled " | │ │ │ │ │ +| "[ supports-utp: %d ]", peerinfo->to_string().c_str() | │ │ │ │ │ +| , peerinfo->supports_utp); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ -| for (int i = settings_pack::bool_type_base; | │ │ │ │ │ -| i < settings_pack::max_bool_setting_internal; ++i) | │ │ │ │ │ +| | │ │ │ │ │ +|aux::socket_type s = [&] { | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| if (peerinfo->is_i2p_addr) | │ │ │ │ │ | { | │ │ │ │ │ -| ret.set_bool(i, m_settings.get_bool(i)); | │ │ │ │ │ +| // It's not entirely obvious why this peer connection is not marked as | │ │ │ │ │ +| // one. The main feature of a peer connection is that whether or not we | │ │ │ │ │ +| // proxy it is configurable. When we use i2p, we want to always prox | │ │ │ │ │ +| // everything via i2p. | │ │ │ │ │ +| | │ │ │ │ │ +| aux::proxy_settings proxy; | │ │ │ │ │ +| proxy.hostname = settings().get_str(settings_pack::i2p_hostname); | │ │ │ │ │ +| proxy.port = std::uint16_t(settings().get_int(settings_pack::i2p_port)); | │ │ │ │ │ +| proxy.type = settings_pack::i2p_proxy; | │ │ │ │ │ +| | │ │ │ │ │ +| aux::socket_type ret = instantiate_connection(m_ses.get_context() | │ │ │ │ │ +| , proxy, nullptr, nullptr, false, false); | │ │ │ │ │ +| i2p_stream& str = boost::get(ret); | │ │ │ │ │ +| str.set_local_i2p_endpoint(m_ses.local_i2p_endpoint()); | │ │ │ │ │ +| str.set_destination(static_cast(peerinfo)->dest()); | │ │ │ │ │ +| str.set_command(i2p_stream::cmd_connect); | │ │ │ │ │ +| str.set_session_id(m_ses.i2p_session()); | │ │ │ │ │ +| return ret; | │ │ │ │ │ | } | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ +| else | │ │ │ │ │ +|#endif | │ │ │ │ │ +| { | │ │ │ │ │ +| void* userdata = nullptr; | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| if (is_ssl_torrent()) | │ │ │ │ │ +|_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_9_1_1_8_ _ _ _ _ _ _ _|_p_e_r_h_a_p_s_ _0_ _s_h_o_u_l_d_ _a_c_t_u_a_l_l_y_ _m_e_a_n_ _0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ppeerrhhaappss 00 sshhoouulldd aaccttuuaallllyy mmeeaann 00 ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::99111188 ****** | │ │ │ │ │ +|// finished torrents may not change their queue positions, as it's set to | │ │ │ │ │ +| // -1 | │ │ │ │ │ +| if ((m_abort || is_finished()) && p != no_pos) return; | │ │ │ │ │ | | │ │ │ │ │ -|namespace { | │ │ │ │ │ -| template | │ │ │ │ │ -| int get_setting_impl(Pack const& p, int name, int*) | │ │ │ │ │ -| { return p.get_int(name); } | │ │ │ │ │ +| TORRENT_ASSERT((p == no_pos) == is_finished() | │ │ │ │ │ +| || (!m_auto_managed && p == no_pos) | │ │ │ │ │ +| || (m_abort && p == no_pos) | │ │ │ │ │ +| || (!m_added && p == no_pos)); | │ │ │ │ │ +| if (p == m_sequence_number) return; | │ │ │ │ │ | | │ │ │ │ │ -| template | │ │ │ │ │ -| bool get_setting_impl(Pack const& p, int name, bool*) | │ │ │ │ │ -| { return p.get_bool(name); } | │ │ │ │ │ +| TORRENT_ASSERT(p >= no_pos); | │ │ │ │ │ | | │ │ │ │ │ -| template | │ │ │ │ │ -| std::string get_setting_impl(Pack const& p, int name, std::string*) | │ │ │ │ │ -|_ _{_ _r_e_t_u_r_n_ _p_._g_e_t___s_t_r_(_n_a_m_e_)_;_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_1_9_9_8 |could this function be merged with expand_unspecified_addresses? right now both listen_endpoint_t and listen_interface_t are almost | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_i_d_e_n_t_i_c_a_l_,_ _m_a_y_b_e_ _t_h_e_ _l_a_t_t_e_r_ _c_o_u_l_d_ _b_e_ _r_e_m_o_v_e_d_ _t_o_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ccoouulldd tthhiiss ffuunnccttiioonn bbee mmeerrggeedd wwiitthh eexxppaanndd__uunnssppeecciiffiieedd__aaddddrreesssseess?? rriigghhtt nnooww bbootthh lliisstteenn__eennddppooiinntt__tt aanndd lliisstteenn__iinntteerrffaaccee__tt aarree aallmmoosstt iiddeennttiiccaall,, mmaayybbee tthhee llaatttteerr ccoouulldd bbee | │ │ │ │ │ -|rreemmoovveedd ttoooo ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::11999988 ****** | │ │ │ │ │ -|session_log("FATAL SESSION ERROR (%s : %d) [%s]" | │ │ │ │ │ -| , ec.category().name(), ec.value(), ec.message().c_str()); | │ │ │ │ │ +| state_updated(); | │ │ │ │ │ +| | │ │ │ │ │ +| m_ses.set_queue_position(this, p); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void torrent::set_max_uploads(int limit, bool const state_update) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +|if (limit <= 0) limit = (1 << 24) - 1; | │ │ │ │ │ +|if (int(m_max_uploads) == limit) return; | │ │ │ │ │ +| if (state_update) state_updated(); | │ │ │ │ │ +| m_max_uploads = aux::numeric_cast(limit); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log() && state_update) | │ │ │ │ │ +| debug_log("*** set-max-uploads: %d", m_max_uploads); | │ │ │ │ │ |#endif | │ │ │ │ │ -| this->abort(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (state_update) | │ │ │ │ │ +| set_need_save_resume(torrent_handle::if_config_changed); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::on_ip_change(error_code const& ec) | │ │ │ │ │ +| void torrent::set_max_connections(int limit, bool const state_update) | │ │ │ │ │ | { | │ │ │ │ │ +|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T_(_i_s___s_i_n_g_l_e___t_h_r_e_a_d_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_9_1_3_5_ _ _ _ _ _ _ _|_p_e_r_h_a_p_s_ _0_ _s_h_o_u_l_d_ _a_c_t_u_a_l_l_y_ _m_e_a_n_ _0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ppeerrhhaappss 00 sshhoouulldd aaccttuuaallllyy mmeeaann 00 ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::99113355 ****** | │ │ │ │ │ +| void torrent::set_max_uploads(int limit, bool const state_update) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| if (limit <= 0) limit = (1 << 24) - 1; | │ │ │ │ │ +| if (int(m_max_uploads) == limit) return; | │ │ │ │ │ +| if (state_update) state_updated(); | │ │ │ │ │ +| m_max_uploads = aux::numeric_cast(limit); | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (!ec) | │ │ │ │ │ -| session_log("received ip change from internal ip_notifier"); | │ │ │ │ │ -| else | │ │ │ │ │ -| session_log("received error on_ip_change: %d, %s", ec.value(), ec.message().c_str()); | │ │ │ │ │ +| if (should_log() && state_update) | │ │ │ │ │ +| debug_log("*** set-max-uploads: %d", m_max_uploads); | │ │ │ │ │ |#endif | │ │ │ │ │ -| if (ec || m_abort || !m_ip_notifier) return; | │ │ │ │ │ -| m_ip_notifier->async_wait([this] (error_code const& e) | │ │ │ │ │ -| { wrap(&session_impl::on_ip_change, e); }); | │ │ │ │ │ -| reopen_network_sockets({}); | │ │ │ │ │ +| | │ │ │ │ │ +| if (state_update) | │ │ │ │ │ +| set_need_save_resume(torrent_handle::if_config_changed); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|void interface_to_endpoints(listen_interface_t const& iface | │ │ │ │ │ -|, listen_socket_flags_t flags | │ │ │ │ │ -| , span const ifs | │ │ │ │ │ -| , std::vector& eps) | │ │ │ │ │ +| void torrent::set_max_connections(int limit, bool const state_update) | │ │ │ │ │ | { | │ │ │ │ │ -| flags |= iface.local ? listen_socket_t::local_network : listen_socket_flags_t{}; | │ │ │ │ │ -| transport const ssl = iface.ssl ? transport::ssl : transport::plaintext; | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +|if (limit <= 0) limit = (1 << 24) - 1; | │ │ │ │ │ +|if (int(m_max_connections) == limit) return; | │ │ │ │ │ +| if (state_update) state_updated(); | │ │ │ │ │ +| m_max_connections = aux::numeric_cast(limit); | │ │ │ │ │ +| update_want_peers(); | │ │ │ │ │ | | │ │ │ │ │ -| // First, check to see if it's an IP address | │ │ │ │ │ -| error_code err; | │ │ │ │ │ -| address const adr = make_address(iface.device.c_str(), err); | │ │ │ │ │ -| if (!err) | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log() && state_update) | │ │ │ │ │ +| debug_log("*** set-max-connections: %d", m_max_connections); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| if (num_peers() > int(m_max_connections)) | │ │ │ │ │ | { | │ │ │ │ │ -| eps.emplace_back(adr, iface.port, std::string{}, ssl, flags); | │ │ │ │ │ +| disconnect_peers(num_peers() - m_max_connections | │ │ │ │ │ +| , errors::too_many_connections); | │ │ │ │ │ | } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| flags |= listen_socket_t::was_expanded; | │ │ │ │ │ | | │ │ │ │ │ -| // this is the case where device names a network device. We need to | │ │ │ │ │ -| // enumerate all IPs associated with this device | │ │ │ │ │ -| for (auto const& ipface : ifs) | │ │ │ │ │ +| if (state_update) | │ │ │ │ │ +| set_need_save_resume(torrent_handle::if_config_changed); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void torrent::set_upload_limit(int const limit) | │ │ │ │ │ +| { | │ │ │ │ │ +| set_limit_impl(limit, peer_connection::upload_channel); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| debug_log("*** set-upload-limit: %d", limit); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void torrent::set_download_limit(int const limit) | │ │ │ │ │ +|_ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_1_0_6_1_ _ _ _ _ _ _|_i_n_s_t_e_a_d_ _o_f_ _r_e_s_o_r_t_i_n_g_ _t_h_e_ _w_h_o_l_e_ _l_i_s_t_,_ _i_n_s_e_r_t_ _t_h_e_ _p_e_e_r_s_ _d_i_r_e_c_t_l_y_ _i_n_t_o_ _t_h_e_ _r_i_g_h_t_ _p_l_a_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinnsstteeaadd ooff rreessoorrttiinngg tthhee wwhhoollee lliisstt,, iinnsseerrtt tthhee ppeeeerrss ddiirreeccttllyy iinnttoo tthhee rriigghhtt ppllaaccee ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::1111006611 ****** | │ │ │ │ │ +|std::printf("timed out [average-piece-time: %d ms ]\n" | │ │ │ │ │ +| , m_average_piece_time); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // pick all blocks for this piece. the peers list is kept up to date | │ │ │ │ │ +| // and sorted. when we issue a request to a peer, its download queue | │ │ │ │ │ +| // time will increase and it may need to be bumped in the peers list, | │ │ │ │ │ +| // since it's ordered by download queue time | │ │ │ │ │ +| pick_time_critical_block(peers, ignore_peers | │ │ │ │ │ +| , peers_with_requests | │ │ │ │ │ +| , pi, &i, m_picker.get() | │ │ │ │ │ +| , blocks_in_piece, timed_out); | │ │ │ │ │ +| | │ │ │ │ │ +| // put back the peers we ignored into the peer list for the next piece | │ │ │ │ │ +| if (!ignore_peers.empty()) | │ │ │ │ │ | { | │ │ │ │ │ -| // we're looking for a specific interface, and its address | │ │ │ │ │ -| // (which must be of the same family as the address we're | │ │ │ │ │ -| // connecting to) | │ │ │ │ │ -| if (iface.device != ipface.name) continue; | │ │ │ │ │ +| peers.insert(peers.begin(), ignore_peers.begin(), ignore_peers.end()); | │ │ │ │ │ +| ignore_peers.clear(); | │ │ │ │ │ | | │ │ │ │ │ -| bool const local = iface.local | │ │ │ │ │ -| || ipface.interface_address.is_loopback() | │ │ │ │ │ -|_ _ _ _ _ _|_|_ _i_s___l_i_n_k___l_o_c_a_l_(_i_p_f_a_c_e_._i_n_t_e_r_f_a_c_e___a_d_d_r_e_s_s_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -| | |it would probably be better to do this by having a listen-socket "version" number that gets bumped. And instead of setting a bool to| │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_2_3_0_6 |disable a tracker, we set the version number that it was disabled at. This change would affect the ABI in 1.2, so should be done in | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_2_._0_ _o_r_ _l_a_t_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd pprroobbaabbllyy bbee bbeetttteerr ttoo ddoo tthhiiss bbyy hhaavviinngg aa lliisstteenn--ssoocckkeett ""vveerrssiioonn"" nnuummbbeerr tthhaatt ggeettss bbuummppeedd.. AAnndd iinnsstteeaadd ooff sseettttiinngg aa bbooooll ttoo ddiissaabbllee aa ttrraacckkeerr,, wwee sseett tthhee | │ │ │ │ │ -|vveerrssiioonn nnuummbbeerr tthhaatt iitt wwaass ddiissaabblleedd aatt.. TThhiiss cchhaannggee wwoouulldd aaffffeecctt tthhee AABBII iinn 11..22,, ssoo sshhoouulldd bbee ddoonnee iinn 22..00 oorr llaatteerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::22330066 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| for (auto const& s : m_listen_sockets) | │ │ │ │ │ -| remap_ports(remap_natpmp_and_upnp, *s); | │ │ │ │ │ +|std::sort(peers.begin(), peers.end() | │ │ │ │ │ +|, [] (peer_connection const* lhs, peer_connection const* rhs) | │ │ │ │ │ +| { return lhs->download_queue_time(16*1024) < rhs->download_queue_time(16*1024); }); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // if this peer's download time exceeds 2 seconds, we're done. | │ │ │ │ │ +| // We don't want to build unreasonably long request queues | │ │ │ │ │ +| if (!peers.empty() && peers[0]->download_queue_time() > milliseconds(2000)) | │ │ │ │ │ +| break; | │ │ │ │ │ | } | │ │ │ │ │ -| else | │ │ │ │ │ +| | │ │ │ │ │ +| // commit all the time critical requests | │ │ │ │ │ +| for (auto p : peers_with_requests) | │ │ │ │ │ | { | │ │ │ │ │ -| // new sockets need to map ports even if the caller did not request | │ │ │ │ │ -| // re-mapping | │ │ │ │ │ -| for (auto const& s : new_sockets) | │ │ │ │ │ -| remap_ports(remap_natpmp_and_upnp, *s); | │ │ │ │ │ +| p->send_block_requests(); | │ │ │ │ │ | } | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif // TORRENT_DISABLE_STREAMING | │ │ │ │ │ | | │ │ │ │ │ -| update_lsd(); | │ │ │ │ │ +| std::set torrent::web_seeds(web_seed_entry::type_t const type) const | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| std::set ret; | │ │ │ │ │ +| for (auto const& s : m_web_seeds) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (s.peer_info.banned) continue; | │ │ │ │ │ +| if (s.removed) continue; | │ │ │ │ │ +| if (s.type != type) continue; | │ │ │ │ │ +| ret.insert(s.url); | │ │ │ │ │ +| } | │ │ │ │ │ +|_ _ _r_e_t_u_r_n_ _r_e_t_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n_._c_p_p_:_5_4_0_ _ _ _ _ _ _ _ _|_I_n_ _C_+_+_1_7_._ _u_s_e_ _i_f_ _c_o_n_s_t_e_x_p_r_ _i_n_s_t_e_a_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** IInn CC++++1177.. uussee iiff ccoonnsstteexxpprr iinnsstteeaadd ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn..ccpppp::554400 ****** | │ │ │ │ │ +|{} | │ │ │ │ │ +| session_proxy::session_proxy(session_proxy const&) = default; | │ │ │ │ │ +| session_proxy& session_proxy::operator=(session_proxy const&) & = default; | │ │ │ │ │ +| session_proxy::session_proxy(session_proxy&&) noexcept = default; | │ │ │ │ │ +| session_proxy& session_proxy::operator=(session_proxy&&) & noexcept = default; | │ │ │ │ │ +| session_proxy::~session_proxy() | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_thread && m_thread.use_count() == 1) | │ │ │ │ │ +| { | │ │ │ │ │ +|#if defined TORRENT_ASIO_DEBUGGING | │ │ │ │ │ +| wait_for_asio_handlers(); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| m_thread->join(); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| open_new_incoming_i2p_connection(); | │ │ │ │ │ +| TORRENT_EXPORT std::unique_ptr default_disk_io_constructor( | │ │ │ │ │ +| io_context& ios, settings_interface const& sett, counters& cnt) | │ │ │ │ │ +| { | │ │ │ │ │ +|#if TORRENT_HAVE_MMAP || TORRENT_HAVE_MAP_VIEW_OF_FILE | │ │ │ │ │ +|#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" | │ │ │ │ │ +|if (sizeof(void*) == 8) | │ │ │ │ │ +| return mmap_disk_io_constructor(ios, sett, cnt); | │ │ │ │ │ +| else | │ │ │ │ │ +| return posix_disk_io_constructor(ios, sett, cnt); | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ +|#else | │ │ │ │ │ +| return posix_disk_io_constructor(ios, sett, cnt); | │ │ │ │ │ |#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // trackers that were not reachable, may have become reachable now. | │ │ │ │ │ -| // so clear the "disabled" flags to let them be tried one more time | │ │ │ │ │ -|for (auto& t : m_torrents) | │ │ │ │ │ -|t->enable_all_trackers(); | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:_4_5_7_ _ _ _|_m_a_y_b_e_ _i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _h_a_v_e_ _a_ _b_e_t_t_e_r_ _i_n_d_e_x_ _h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmaayybbee iitt wwoouulldd bbee nniiccee ttoo hhaavvee aa bbeetttteerr iinnddeexx hheerree ********** | │ │ │ │ │ +|****** ....//ssrrcc//ffiillee__ssttoorraaggee..ccpppp::445577 ****** | │ │ │ │ │ +|// find the file iterator and file offset | │ │ │ │ │ +| aux::file_entry target; | │ │ │ │ │ +| target.offset = aux::numeric_cast(offset); | │ │ │ │ │ +| TORRENT_ASSERT(!compare_file_offset(target, m_files.front())); | │ │ │ │ │ +| | │ │ │ │ │ +| auto file_iter = std::upper_bound( | │ │ │ │ │ +| m_files.begin(), m_files.end(), target, compare_file_offset); | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(file_iter != m_files.begin()); | │ │ │ │ │ +| --file_iter; | │ │ │ │ │ +| return file_index_t{int(file_iter - m_files.begin())}; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::reopen_network_sockets(reopen_network_flags_t const options) | │ │ │ │ │ +| file_index_t file_storage::file_index_at_piece(piece_index_t const piece) const | │ │ │ │ │ | { | │ │ │ │ │ -| reopen_listen_sockets(bool(options & session_handle::reopen_map_ports)); | │ │ │ │ │ +| return file_index_at_offset(static_cast(piece) * std::int64_t(piece_length())); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| namespace { | │ │ │ │ │ -| template | │ │ │ │ │ -| void map_port(MapProtocol& m, ProtoType protocol, EndpointType const& ep | │ │ │ │ │ -| , port_mapping_t& map_handle, std::string const& device) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (map_handle != port_mapping_t{-1}) m.delete_mapping(map_handle); | │ │ │ │ │ -| map_handle = port_mapping_t{-1}; | │ │ │ │ │ +| file_index_t file_storage::file_index_for_root(sha256_hash const& root_hash) const | │ │ │ │ │ +| { | │ │ │ │ │ +|for (file_index_t const i : file_range()) | │ │ │ │ │ +|{ | │ │ │ │ │ +| if (root(i) == root_hash) return i; | │ │ │ │ │ +| } | │ │ │ │ │ +| return file_index_t{-1}; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| address const addr = ep.address(); | │ │ │ │ │ -| // with IPv4 the interface might be behind NAT so we can't skip them | │ │ │ │ │ -| // based on the scope of the local address | │ │ │ │ │ -| if (addr.is_v6() && is_local(addr)) | │ │ │ │ │ -| return; | │ │ │ │ │ +| piece_index_t file_storage::piece_index_at_file(file_index_t f) const | │ │ │ │ │ +| { | │ │ │ │ │ +| return piece_index_t{aux::numeric_cast(file_offset(f) / piece_length())}; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // only update this mapping if we actually have a socket listening | │ │ │ │ │ -| if (ep != EndpointType()) | │ │ │ │ │ -| map_handle = m.add_mapping(protocol, ep.port(), ep, device); | │ │ │ │ │ -| } | │ │ │ │ │ +|#if TORRENT_ABI_VERSION <= 2 | │ │ │ │ │ +| char const* file_storage::file_name_ptr(file_index_t const index) const | │ │ │ │ │ +| { | │ │ │ │ │ +| return m_files[index].name; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::remap_ports(remap_port_mask_t const mask | │ │ │ │ │ -|_ _ _,_ _l_i_s_t_e_n___s_o_c_k_e_t___t_&_ _s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_2_8_6_6_ _ _|_t_h_i_s_ _s_i_z_e_ _n_e_e_d_ _t_o_ _b_e_ _c_a_p_p_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ssiizzee nneeeedd ttoo bbee ccaappppeedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::22886666 ****** | │ │ │ │ │ -|// handshaking | │ │ │ │ │ -| return socket_type(ssl_stream(tcp::socket(std::move(s)), m_peer_ssl_ctx)); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ +| int file_storage::file_name_len(file_index_t const index) const | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_files[index].name_len == aux::file_entry::name_is_owned) | │ │ │ │ │ +| return -1; | │ │ │ │ │ +| return m_files[index].name_len; | │ │ │ │ │ +| } | │ │ │ │ │ |#endif | │ │ │ │ │ +| | │ │ │ │ │ +| std::vector file_storage::map_block(piece_index_t const piece | │ │ │ │ │ +| , std::int64_t const offset, std::int64_t size) const | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT_PRECOND(piece >= piece_index_t{0}); | │ │ │ │ │ +|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T___P_R_E_C_O_N_D_(_p_i_e_c_e_ _<_ _e_n_d___p_i_e_c_e_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:_1_2_4_2_ _ _|_t_h_i_s_ _w_o_u_l_d_ _b_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_ _i_f_ _m___p_a_t_h_s_ _w_a_s_ _s_o_r_t_e_d_ _f_i_r_s_t_,_ _s_u_c_h_ _t_h_a_t_ _a_ _l_o_w_e_r_ _p_a_t_h_ _i_n_d_e_x_ _a_l_w_a_y_s_ _m_e_a_n_t_ _s_o_r_t_e_d_-_b_e_f_o_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss wwoouulldd bbee mmoorree eeffffiicciieenntt iiff mm__ppaatthhss wwaass ssoorrtteedd ffiirrsstt,, ssuucchh tthhaatt aa lloowweerr ppaatthh iinnddeexx aallwwaayyss mmeeaanntt ssoorrtteedd--bbeeffoorree ********** | │ │ │ │ │ +|****** ....//ssrrcc//ffiillee__ssttoorraaggee..ccpppp::11224422 ****** | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| void file_storage::canonicalize_impl(bool const backwards_compatible) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(piece_length() >= 16 * 1024); | │ │ │ │ │ +| | │ │ │ │ │ +| // use this vector to track the new ordering of files | │ │ │ │ │ +| // this allows the use of STL algorithms despite them | │ │ │ │ │ +| // not supporting a custom swap functor | │ │ │ │ │ +| aux::vector new_order(end_file()); | │ │ │ │ │ +| for (auto i : file_range()) | │ │ │ │ │ +| new_order[i] = i; | │ │ │ │ │ +| | │ │ │ │ │ +| // remove any existing pad files | │ │ │ │ │ +| { | │ │ │ │ │ +| auto pad_begin = std::partition(new_order.begin(), new_order.end() | │ │ │ │ │ +| , [this](file_index_t i) { return !m_files[i].pad_file; }); | │ │ │ │ │ +| new_order.erase(pad_begin, new_order.end()); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|// sort files by path/name | │ │ │ │ │ +| std::sort(new_order.begin(), new_order.end() | │ │ │ │ │ +| , [this](file_index_t l, file_index_t r) | │ │ │ │ │ +| { | │ │ │ │ │ +| // assuming m_paths are unique! | │ │ │ │ │ +| auto const& lf = m_files[l]; | │ │ │ │ │ +| auto const& rf = m_files[r]; | │ │ │ │ │ +| if (lf.path_index != rf.path_index) | │ │ │ │ │ | { | │ │ │ │ │ -| return socket_type(tcp::socket(std::move(s))); | │ │ │ │ │ +| int const ret = path_compare(m_paths[lf.path_index], lf.filename() | │ │ │ │ │ +| , m_paths[rf.path_index], rf.filename()); | │ │ │ │ │ +| if (ret != 0) return ret < 0; | │ │ │ │ │ | } | │ │ │ │ │ -| }(); | │ │ │ │ │ +| return lf.filename() < rf.filename(); | │ │ │ │ │ +| }); | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| TORRENT_ASSERT((ssl == transport::ssl) == is_ssl(c)); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| aux::vector new_files; | │ │ │ │ │ +| aux::vector new_file_hashes; | │ │ │ │ │ +| aux::vector new_mtime; | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| if (ssl == transport::ssl) | │ │ │ │ │ +| // reserve enough space for the worst case after padding | │ │ │ │ │ +| new_files.reserve(new_order.size() * 2 - 1); | │ │ │ │ │ +| if (!m_file_hashes.empty()) | │ │ │ │ │ +| new_file_hashes.reserve(new_order.size() * 2 - 1); | │ │ │ │ │ +| if (!m_mtime.empty()) | │ │ │ │ │ +| new_mtime.reserve(new_order.size() * 2 - 1); | │ │ │ │ │ +| | │ │ │ │ │ +| // re-compute offsets and insert pad files as necessary | │ │ │ │ │ +|_ _ _s_t_d_:_:_i_n_t_6_4___t_ _o_f_f_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:_1_3_4_5_ _ _|_i_n_ _C_+_+_1_7_ _t_h_i_s_ _c_o_u_l_d_ _b_e_ _s_t_r_i_n_g___v_i_e_w_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinn CC++++1177 tthhiiss ccoouulldd bbee ssttrriinngg__vviieeww ********** | │ │ │ │ │ +|****** ....//ssrrcc//ffiillee__ssttoorraaggee..ccpppp::11334455 ****** | │ │ │ │ │ +|add_pad_file(i); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| m_files = std::move(new_files); | │ │ │ │ │ +| m_file_hashes = std::move(new_file_hashes); | │ │ │ │ │ +| m_mtime = std::move(new_mtime); | │ │ │ │ │ +| | │ │ │ │ │ +| m_total_size = off; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void file_storage::sanitize_symlinks() | │ │ │ │ │ +| { | │ │ │ │ │ +| // symlinks are unusual, this function is optimized assuming there are no | │ │ │ │ │ +| // symbolic links in the torrent. If we find one symbolic link, we'll | │ │ │ │ │ +| // build the hash table of files it's allowed to refer to, but don't pay | │ │ │ │ │ +| // that price up-front. | │ │ │ │ │ +| std::unordered_map file_map; | │ │ │ │ │ +| bool file_map_initialized = false; | │ │ │ │ │ +| | │ │ │ │ │ +| // lazily instantiated set of all valid directories a symlink may point to | │ │ │ │ │ +|std::unordered_set dir_map; | │ │ │ │ │ +|bool dir_map_initialized = false; | │ │ │ │ │ +| | │ │ │ │ │ +| // symbolic links that points to directories | │ │ │ │ │ +| std::unordered_map dir_links; | │ │ │ │ │ +| | │ │ │ │ │ +| // we validate symlinks in (potentially) 2 passes over the files. | │ │ │ │ │ +| // remaining symlinks to validate after the first pass | │ │ │ │ │ +| std::vector symlinks_to_validate; | │ │ │ │ │ +| | │ │ │ │ │ +| for (auto const i : file_range()) | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(is_ssl(c)); | │ │ │ │ │ +| if (!(file_flags(i) & file_storage::flag_symlink)) continue; | │ │ │ │ │ | | │ │ │ │ │ -| // save the socket so we can cancel the handshake | │ │ │ │ │ -|auto iter = m_incoming_sockets.emplace(std::make_unique(std::move(c))).first; | │ │ │ │ │ +| if (!file_map_initialized) | │ │ │ │ │ +| { | │ │ │ │ │ +| for (auto const j : file_range()) | │ │ │ │ │ +| file_map.insert({internal_file_path(j), j}); | │ │ │ │ │ +| file_map_initialized = true; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| auto sock = iter->get(); | │ │ │ │ │ -| // for SSL connections, incoming_connection() is called | │ │ │ │ │ -| // after the handshake is done | │ │ │ │ │ -| ADD_OUTSTANDING_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ -| boost::get>(**iter).async_accept_handshake( | │ │ │ │ │ -| [this, sock] (error_code const& err) { ssl_handshake(err, sock); }); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -|#endif | │ │ │ │ │ +| aux::file_entry const& fe = m_files[i]; | │ │ │ │ │ +| TORRENT_ASSERT(fe.symlink_index < int(m_symlinks.size())); | │ │ │ │ │ +| | │ │ │ │ │ +| // symlink targets are only allowed to point to files or directories in | │ │ │ │ │ +| // this torrent. | │ │ │ │ │ +| { | │ │ │ │ │ +| std::string target = m_symlinks[fe.symlink_index]; | │ │ │ │ │ +| | │ │ │ │ │ +| if (is_complete(target)) | │ │ │ │ │ +|_ _ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/ |introduce a web-seed default class which has a low download priority | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_w_e_b___c_o_n_n_e_c_t_i_o_n___b_a_s_e_._c_p_p_:_7_2_ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinnttrroodduuccee aa wweebb--sseeeedd ddeeffaauulltt ccllaassss wwhhiicchh hhaass aa llooww ddoowwnnllooaadd pprriioorriittyy ********** | │ │ │ │ │ +|****** ....//ssrrcc//wweebb__ccoonnnneeccttiioonn__bbaassee..ccpppp::7722 ****** | │ │ │ │ │ +|: peer_connection(pack) | │ │ │ │ │ +| , m_first_request(true) | │ │ │ │ │ +| , m_ssl(false) | │ │ │ │ │ +| , m_external_auth(web.auth) | │ │ │ │ │ +| , m_extra_headers(web.extra_headers) | │ │ │ │ │ +| , m_parser(http_parser::dont_parse_chunks) | │ │ │ │ │ +| , m_body_start(0) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(&web.peer_info == pack.peerinfo); | │ │ │ │ │ +| // when going through a proxy, we don't necessarily have an endpoint here, | │ │ │ │ │ +| // since the proxy might be resolving the hostname, not us | │ │ │ │ │ +| TORRENT_ASSERT(web.endpoints.empty() || web.endpoints.front() == pack.endp); | │ │ │ │ │ +| | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(is_outgoing()); | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(!m_torrent.lock()->is_upload_only()); | │ │ │ │ │ +| | │ │ │ │ │ +| // we only want left-over bandwidth | │ │ │ │ │ +| | │ │ │ │ │ +|std::string protocol; | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| std::tie(protocol, m_basic_auth, m_host, m_port, m_path) | │ │ │ │ │ +| = parse_url_components(web.url, ec); | │ │ │ │ │ +| TORRENT_ASSERT(!ec); | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_port == -1 && protocol == "http") | │ │ │ │ │ +| m_port = 80; | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_USE_SSL | │ │ │ │ │ +| if (protocol == "https") | │ │ │ │ │ | { | │ │ │ │ │ -| incoming_connection(std::move(c)); | │ │ │ │ │ +| m_ssl = true; | │ │ │ │ │ +| if (m_port == -1) m_port = 443; | │ │ │ │ │ | } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| if (!m_basic_auth.empty()) | │ │ │ │ │ +| m_basic_auth = base64encode(m_basic_auth); | │ │ │ │ │ +| | │ │ │ │ │ +| m_server_string = m_host; | │ │ │ │ │ +| aux::verify_encoding(m_server_string); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| int web_connection_base::timeout() const | │ │ │ │ │ +| { | │ │ │ │ │ +| // since this is a web seed, change the timeout | │ │ │ │ │ +| // according to the settings. | │ │ │ │ │ +| return m_settings.get_int(settings_pack::urlseed_timeout); | │ │ │ │ │ +|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_c_p_u_i_d_._c_p_p_:_1_3_1_ _ _ _ _ _ _ _ _ _ _|_e_n_a_b_l_e_ _w_h_e_n_ _a_a_r_c_h_6_4_ _i_s_ _r_e_a_l_l_y_ _t_e_s_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** eennaabbllee wwhheenn aaaarrcchh6644 iiss rreeaallllyy tteesstteedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//ccppuuiidd..ccpppp::113311 ****** | │ │ │ │ │ +|bool supports_mmx() noexcept | │ │ │ │ │ +| { | │ │ │ │ │ +|#if TORRENT_HAS_SSE | │ │ │ │ │ +| std::uint32_t cpui[4] = {0}; | │ │ │ │ │ +| cpuid(cpui, 1); | │ │ │ │ │ +| return (cpui[2] & (1 << 23)) != 0; | │ │ │ │ │ +|#else | │ │ │ │ │ +| return false; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::on_incoming_utp_ssl(socket_type s) | │ │ │ │ │ +| bool supports_arm_neon() noexcept | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(is_ssl(s)); | │ │ │ │ │ +|#if TORRENT_HAS_ARM_NEON && TORRENT_HAS_AUXV | │ │ │ │ │ +|#if defined __arm__ | │ │ │ │ │ +| //return (getauxval(AT_HWCAP) & HWCAP_NEON); | │ │ │ │ │ +| return (helper_getauxval(16) & (1 << 12)); | │ │ │ │ │ +|#elif defined __aarch64__ | │ │ │ │ │ +| //return (getauxval(AT_HWCAP) & HWCAP_ASIMD); | │ │ │ │ │ +| //return (getauxval(16) & (1 << 1)); | │ │ │ │ │ +|return false; | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#else | │ │ │ │ │ +| return false; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|_ _ _/_/_ _s_a_v_e_ _t_h_e_ _s_o_c_k_e_t_ _s_o_ _w_e_ _c_a_n_ _c_a_n_c_e_l_ _t_h_e_ _h_a_n_d_s_h_a_k_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_2_8_9_1_ _ _|_t_h_i_s_ _s_i_z_e_ _n_e_e_d_ _t_o_ _b_e_ _c_a_p_p_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ssiizzee nneeeedd ttoo bbee ccaappppeedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::22889911 ****** | │ │ │ │ │ -|// after the handshake is done | │ │ │ │ │ -| ADD_OUTSTANDING_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ -| boost::get>(**iter).async_accept_handshake( | │ │ │ │ │ -| [this, sock] (error_code const& err) { ssl_handshake(err, sock); }); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ +| bool supports_arm_crc32c() noexcept | │ │ │ │ │ +| { | │ │ │ │ │ +|#if TORRENT_HAS_ARM_CRC32 && TORRENT_HAS_AUXV | │ │ │ │ │ +|#if defined TORRENT_FORCE_ARM_CRC32 | │ │ │ │ │ +| return true; | │ │ │ │ │ +|#elif defined __arm__ | │ │ │ │ │ +| //return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); | │ │ │ │ │ +| return (helper_getauxval(26) & (1 << 4)); | │ │ │ │ │ +|#elif defined __aarch64__ | │ │ │ │ │ +| //return (getauxval(AT_HWCAP) & HWCAP_CRC32); | │ │ │ │ │ +| return (helper_getauxval(16) & (1 << 7)); | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#else | │ │ │ │ │ +| return false; | │ │ │ │ │ |#endif | │ │ │ │ │ -| { | │ │ │ │ │ -| incoming_connection(std::move(c)); | │ │ │ │ │ -| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +|} // anonymous namespace | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::on_incoming_utp_ssl(socket_type s) | │ │ │ │ │ +| bool const sse42_support = supports_sse42(); | │ │ │ │ │ +| bool const mmx_support = supports_mmx(); | │ │ │ │ │ +| bool const arm_neon_support = supports_arm_neon(); | │ │ │ │ │ +| bool const arm_crc32c_support = supports_arm_crc32c(); | │ │ │ │ │ +|_}_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_d_i_s_a_b_l_e_d___d_i_s_k___i_o_._c_p_p_: |it would be nice to return a valid hash of zeroes here | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_1_0_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo rreettuurrnn aa vvaalliidd hhaasshh ooff zzeerrooeess hheerree ********** | │ │ │ │ │ +|****** ....//ssrrcc//ddiissaabblleedd__ddiisskk__iioo..ccpppp::110066 ****** | │ │ │ │ │ +|}); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| bool async_write(storage_index_t | │ │ │ │ │ +| , peer_request const& r | │ │ │ │ │ +| , char const*, std::shared_ptr | │ │ │ │ │ +| , std::function handler | │ │ │ │ │ +| , disk_job_flags_t) override | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(is_ssl(s)); | │ │ │ │ │ +| TORRENT_ASSERT(r.length <= default_block_size); | │ │ │ │ │ +| TORRENT_UNUSED(r); | │ │ │ │ │ | | │ │ │ │ │ -| // save the socket so we can cancel the handshake | │ │ │ │ │ +| post(m_ios, [h = std::move(handler)] { h(storage_error{}); }); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|auto iter = m_incoming_sockets.emplace(std::make_unique(std::move(s))).first; | │ │ │ │ │ -|auto sock = iter->get(); | │ │ │ │ │ +| void async_hash(storage_index_t | │ │ │ │ │ +| , piece_index_t piece, span, disk_job_flags_t | │ │ │ │ │ +| , std::function handler) override | │ │ │ │ │ +| { | │ │ │ │ │ +|post(m_ios, [h = std::move(handler), piece] { h(piece, sha1_hash{}, storage_error{}); }); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| // for SSL connections, incoming_connection() is called | │ │ │ │ │ -| // after the handshake is done | │ │ │ │ │ -| ADD_OUTSTANDING_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ -| boost::get>(**iter).async_accept_handshake( | │ │ │ │ │ -| [this, sock] (error_code const& err) { ssl_handshake(err, sock); }); | │ │ │ │ │ +| void async_hash2(storage_index_t, piece_index_t piece, int | │ │ │ │ │ +| , disk_job_flags_t | │ │ │ │ │ +| , std::function handler) override | │ │ │ │ │ +| { | │ │ │ │ │ +| post(m_ios, [h = std::move(handler), piece]() { h(piece, sha256_hash{}, storage_error{}); }); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // to test SSL connections, one can use this openssl command template: | │ │ │ │ │ -| // | │ │ │ │ │ -| // openssl s_client -cert .pem -key .pem | │ │ │ │ │ -| // -CAfile .pem -debug -connect 127.0.0.1:4433 -tls1 | │ │ │ │ │ -| // -servername | │ │ │ │ │ +| void async_move_storage(storage_index_t | │ │ │ │ │ +| , std::string p, move_flags_t | │ │ │ │ │ +| , std::function handler) override | │ │ │ │ │ +| { | │ │ │ │ │ +| post(m_ios, [h = std::move(handler), path = std::move(p)] () mutable | │ │ │ │ │ +| { h(status_t::no_error, std::move(path), storage_error{}); }); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::ssl_handshake(error_code const& ec, socket_type* sock) | │ │ │ │ │ +| void async_release_files(storage_index_t, std::function handler) override | │ │ │ │ │ | { | │ │ │ │ │ -| COMPLETE_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ +| post(m_ios, [h = std::move(handler)] { h(); }); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| auto iter = m_incoming_sockets.find(sock); | │ │ │ │ │ +| void async_delete_files(storage_index_t | │ │ │ │ │ +| , remove_flags_t, std::function handler) override | │ │ │ │ │ +| { | │ │ │ │ │ +| post(m_ios, [h = std::move(handler)] { h(storage_error{}); }); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // this happens if the SSL connection is aborted because we're shutting | │ │ │ │ │ -| // down | │ │ │ │ │ -| if (iter == m_incoming_sockets.end()) return; | │ │ │ │ │ +| void async_check_files(storage_index_t | │ │ │ │ │ +|_ _ _,_ _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_ _c_o_n_s_t_*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_u_d_p___s_o_c_k_e_t_._c_p_p_:_6_5_9_ _ _ _ _ _|_p_e_r_h_a_p_s_ _a_n_ _a_t_t_e_m_p_t_ _s_h_o_u_l_d_ _b_e_ _m_a_d_e_ _t_o_ _b_i_n_d_ _m___s_o_c_k_s_5___s_o_c_k_ _t_o_ _t_h_e_ _d_e_v_i_c_e_ _o_f_ _m___l_i_s_t_e_n___s_o_c_k_e_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ppeerrhhaappss aann aatttteemmpptt sshhoouulldd bbee mmaaddee ttoo bbiinndd mm__ssoocckkss55__ssoocckk ttoo tthhee ddeevviiccee ooff mm__lliisstteenn__ssoocckkeett ********** | │ │ │ │ │ +|****** ....//ssrrcc//uuddpp__ssoocckkeett..ccpppp::665599 ****** | │ │ │ │ │ +|if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_alerts.should_post()) | │ │ │ │ │ +| m_alerts.emplace_alert(m_proxy_addr, operation_t::sock_option, ec); | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| socket_type s(std::move(**iter)); | │ │ │ │ │ -| TORRENT_ASSERT(is_ssl(s)); | │ │ │ │ │ -| m_incoming_sockets.erase(iter); | │ │ │ │ │ +| tcp::endpoint const bind_ep(m_listen_socket.get_local_endpoint().address(), 0); | │ │ │ │ │ +| m_socks5_sock.bind(bind_ep, ec); | │ │ │ │ │ +| if (ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_alerts.should_post()) | │ │ │ │ │ +| m_alerts.emplace_alert(m_proxy_addr, operation_t::sock_bind, ec); | │ │ │ │ │ +| ++m_failures; | │ │ │ │ │ +| retry_connection(); | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|_ _ _e_r_r_o_r___c_o_d_e_ _e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_3_5_9_0_ _ _|_h_a_v_e_ _a_ _s_e_p_a_r_a_t_e_ _l_i_s_t_ _f_o_r_ _t_h_e_s_e_ _c_o_n_n_e_c_t_i_o_n_s_,_ _i_n_s_t_e_a_d_ _o_f_ _h_a_v_i_n_g_ _t_o_ _l_o_o_p_ _t_h_r_o_u_g_h_ _a_l_l_ _o_f_ _t_h_e_m_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** hhaavvee aa sseeppaarraattee lliisstt ffoorr tthheessee ccoonnnneeccttiioonnss,, iinnsstteeaadd ooff hhaavviinngg ttoo lloooopp tthhrroouugghh aallll ooff tthheemm ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::33559900 ****** | │ │ │ │ │ -|// -------------------------------------------------------------- | │ │ │ │ │ -| if (!m_paused) m_auto_manage_time_scaler--; | │ │ │ │ │ -| if (m_auto_manage_time_scaler < 0) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_auto_manage_time_scaler = settings().get_int(settings_pack::auto_manage_interval); | │ │ │ │ │ -| recalculate_auto_managed_torrents(); | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| // -------------------------------------------------------------- | │ │ │ │ │ -| // check for incoming connections that might have timed out | │ │ │ │ │ -| // -------------------------------------------------------------- | │ │ │ │ │ +|ADD_OUTSTANDING_ASYNC("socks5::on_connected"); | │ │ │ │ │ +| m_socks5_sock.async_connect(m_proxy_addr | │ │ │ │ │ +| , std::bind(&socks5::on_connected, self(), _1)); | │ │ │ │ │ | | │ │ │ │ │ -| for (auto i = m_connections.begin(); i != m_connections.end();) | │ │ │ │ │ -| { | │ │ │ │ │ -| peer_connection* p = (*i).get(); | │ │ │ │ │ -| ++i; | │ │ │ │ │ -| // ignore connections that already have a torrent, since they | │ │ │ │ │ -| // are ticked through the torrents' second_tick | │ │ │ │ │ -| if (!p->associated_torrent().expired()) continue; | │ │ │ │ │ +| ADD_OUTSTANDING_ASYNC("socks5::on_connect_timeout"); | │ │ │ │ │ +| m_timer.expires_after(seconds(10)); | │ │ │ │ │ +| m_timer.async_wait(std::bind(&socks5::on_connect_timeout | │ │ │ │ │ +| , self(), _1)); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -|int timeout = m_settings.get_int(settings_pack::handshake_timeout); | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| timeout *= is_i2p(p->get_socket()) ? 4 : 1; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| if (m_last_tick - p->connected_time () > seconds(timeout)) | │ │ │ │ │ -| p->disconnect(errors::timed_out, operation_t::bittorrent); | │ │ │ │ │ -| } | │ │ │ │ │ +|void socks5::on_connect_timeout(error_code const& e) | │ │ │ │ │ +|{ | │ │ │ │ │ +| COMPLETE_ASYNC("socks5::on_connect_timeout"); | │ │ │ │ │ | | │ │ │ │ │ -| // -------------------------------------------------------------- | │ │ │ │ │ -| // second_tick every torrent (that wants it) | │ │ │ │ │ -| // -------------------------------------------------------------- | │ │ │ │ │ +| if (e == boost::asio::error::operation_aborted) return; | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_DEBUG_STREAMING > 0 | │ │ │ │ │ -| std::printf("\033[2J\033[0;0H"); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| if (m_abort) return; | │ │ │ │ │ | | │ │ │ │ │ -| aux::vector& want_tick = m_torrent_lists[torrent_want_tick]; | │ │ │ │ │ -| for (int i = 0; i < int(want_tick.size()); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| torrent& t = *want_tick[i]; | │ │ │ │ │ -| TORRENT_ASSERT(t.want_tick()); | │ │ │ │ │ -| TORRENT_ASSERT(!t.is_aborted()); | │ │ │ │ │ +| if (m_alerts.should_post()) | │ │ │ │ │ +| m_alerts.emplace_alert(m_proxy_addr, operation_t::connect, errors::timed_out); | │ │ │ │ │ | | │ │ │ │ │ -| t.second_tick(tick_interval_ms); | │ │ │ │ │ +| error_code ignore; | │ │ │ │ │ +| m_socks5_sock.close(ignore); | │ │ │ │ │ | | │ │ │ │ │ -| // if the call to second_tick caused the torrent | │ │ │ │ │ -| // to no longer want to be ticked (i.e. it was | │ │ │ │ │ -| // removed from the list) we need to back up the counter | │ │ │ │ │ -| // to not miss the torrent after it | │ │ │ │ │ -| if (!t.want_tick()) --i; | │ │ │ │ │ -|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_3_6_2_3_ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _a_p_p_l_y_ _t_o_ _a_l_l_ _b_a_n_d_w_i_d_t_h_ _c_h_a_n_n_e_l_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd aappppllyy ttoo aallll bbaannddwwiiddtthh cchhaannnneellss ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::33662233 ****** | │ │ │ │ │ -|#if TORRENT_DEBUG_STREAMING > 0 | │ │ │ │ │ -| std::printf("\033[2J\033[0;0H"); | │ │ │ │ │ +| ++m_failures; | │ │ │ │ │ +| retry_connection(); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|void socks5::on_connected(error_code const& e) | │ │ │ │ │ +|_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_p_o_s_i_x___p_a_r_t___f_i_l_e_._c_p_p_:_3_3_7|what do we do if someone is currently reading from the disk from this piece? does it matter? Since we won't actively erase the data | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_f_r_o_m_ _d_i_s_k_,_ _b_u_t_ _i_t_ _m_a_y_ _b_e_ _o_v_e_r_w_r_i_t_t_e_n_ _s_o_o_n_,_ _i_t_'_s_ _p_r_o_b_a_b_l_y_ _n_o_t_ _t_h_a_t_ _b_i_g_ _o_f_ _a_ _d_e_a_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** wwhhaatt ddoo wwee ddoo iiff ssoommeeoonnee iiss ccuurrrreennttllyy rreeaaddiinngg ffrroomm tthhee ddiisskk ffrroomm tthhiiss ppiieeccee?? ddooeess iitt mmaatttteerr?? SSiinnccee wwee wwoonn''tt aaccttiivveellyy eerraassee tthhee ddaattaa ffrroomm ddiisskk,, bbuutt iitt mmaayy bbee oovveerrwwrriitttteenn | │ │ │ │ │ +|ssoooonn,, iitt''ss pprroobbaabbllyy nnoott tthhaatt bbiigg ooff aa ddeeaall ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppoossiixx__ppaarrtt__ffiillee..ccpppp::333377 ****** | │ │ │ │ │ +| if (ec) return {}; | │ │ │ │ │ +| | │ │ │ │ │ +|#ifdef TORRENT_WINDOWS | │ │ │ │ │ +| ret = file_pointer(::_wfopen(convert_to_native_path_string(fn).c_str(), L"wb+")); | │ │ │ │ │ +|#else | │ │ │ │ │ +| ret = file_pointer(::fopen(fn.c_str(), "wb+")); | │ │ │ │ │ |#endif | │ │ │ │ │ +| if (ret.file() == nullptr) | │ │ │ │ │ +| ec.assign(errno, generic_category()); | │ │ │ │ │ +| } | │ │ │ │ │ +| if (ec) return {}; | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| aux::vector& want_tick = m_torrent_lists[torrent_want_tick]; | │ │ │ │ │ -| for (int i = 0; i < int(want_tick.size()); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| torrent& t = *want_tick[i]; | │ │ │ │ │ -| TORRENT_ASSERT(t.want_tick()); | │ │ │ │ │ -| TORRENT_ASSERT(!t.is_aborted()); | │ │ │ │ │ +| void posix_part_file::free_piece(piece_index_t const piece) | │ │ │ │ │ +| { | │ │ │ │ │ +| auto const i = m_piece_map.find(piece); | │ │ │ │ │ +| if (i == m_piece_map.end()) return; | │ │ │ │ │ | | │ │ │ │ │ -| t.second_tick(tick_interval_ms); | │ │ │ │ │ | | │ │ │ │ │ -| // if the call to second_tick caused the torrent | │ │ │ │ │ -| // to no longer want to be ticked (i.e. it was | │ │ │ │ │ -| // removed from the list) we need to back up the counter | │ │ │ │ │ -| // to not miss the torrent after it | │ │ │ │ │ -| if (!t.want_tick()) --i; | │ │ │ │ │ -| } | │ │ │ │ │ +|m_free_slots.push_back(i->second); | │ │ │ │ │ +| m_piece_map.erase(i); | │ │ │ │ │ +| m_dirty_metadata = true; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|if (m_settings.get_bool(settings_pack::rate_limit_ip_overhead)) | │ │ │ │ │ -|{ | │ │ │ │ │ -| int const up_limit = upload_rate_limit(m_global_class); | │ │ │ │ │ -| int const down_limit = download_rate_limit(m_global_class); | │ │ │ │ │ +| void posix_part_file::move_partfile(std::string const& path, error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| flush_metadata_impl(ec); | │ │ │ │ │ +| if (ec) return; | │ │ │ │ │ | | │ │ │ │ │ -| if (down_limit > 0 | │ │ │ │ │ -| && m_stat.download_ip_overhead() >= down_limit | │ │ │ │ │ -| && m_alerts.should_post()) | │ │ │ │ │ +| if (!m_piece_map.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::string old_path = combine_path(m_path, m_name); | │ │ │ │ │ +| std::string new_path = combine_path(path, m_name); | │ │ │ │ │ +| | │ │ │ │ │ +| rename(old_path, new_path, ec); | │ │ │ │ │ +| if (ec == boost::system::errc::no_such_file_or_directory) | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| | │ │ │ │ │ +| if (ec) | │ │ │ │ │ | { | │ │ │ │ │ -| m_alerts.emplace_alert(torrent_handle() | │ │ │ │ │ -| , performance_alert::download_limit_too_low); | │ │ │ │ │ +| storage_error se; | │ │ │ │ │ +| aux::copy_file(old_path, new_path, se); | │ │ │ │ │ +| ec = se.ec; | │ │ │ │ │ +| if (ec) return; | │ │ │ │ │ +| remove(old_path, ec); | │ │ │ │ │ | } | │ │ │ │ │ +| } | │ │ │ │ │ +| m_path = path; | │ │ │ │ │ +|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_o_s_i_x___p_a_r_t___f_i_l_e_._c_p_p_:_4_2_4_|_i_n_s_t_e_a_d_ _o_f_ _r_e_b_u_i_l_d_i_n_g_ _t_h_e_ _w_h_o_l_e_ _f_i_l_e_ _h_e_a_d_e_r_ _a_n_d_ _f_l_u_s_h_i_n_g_ _i_t_,_ _u_p_d_a_t_e_ _t_h_e_ _s_l_o_t_ _e_n_t_r_i_e_s_ _a_s_ _w_e_ _g_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinnsstteeaadd ooff rreebbuuiillddiinngg tthhee wwhhoollee ffiillee hheeaaddeerr aanndd fflluusshhiinngg iitt,, uuppddaattee tthhee sslloott eennttrriieess aass wwee ggoo ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppoossiixx__ppaarrtt__ffiillee..ccpppp::442244 ****** | │ │ │ │ │ +|} | │ │ │ │ │ +| auto bytes_read = std::fread(buf.get(), 1, std::size_t(block_to_copy), file.file()); | │ │ │ │ │ +| if (int(bytes_read) != block_to_copy) | │ │ │ │ │ +| ec.assign(errno, generic_category()); | │ │ │ │ │ | | │ │ │ │ │ -| if (up_limit > 0 | │ │ │ │ │ -| && m_stat.upload_ip_overhead() >= up_limit | │ │ │ │ │ -| && m_alerts.should_post()) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_alerts.emplace_alert(torrent_handle() | │ │ │ │ │ -| , performance_alert::upload_limit_too_low); | │ │ │ │ │ +| if (ec) return; | │ │ │ │ │ +| | │ │ │ │ │ +| f(file_offset, {buf.get(), block_to_copy}); | │ │ │ │ │ | } | │ │ │ │ │ +| file_offset += block_to_copy; | │ │ │ │ │ +| piece_offset = 0; | │ │ │ │ │ +| size -= block_to_copy; | │ │ │ │ │ | } | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| m_peak_up_rate = std::max(m_stat.upload_rate(), m_peak_up_rate); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| void posix_part_file::flush_metadata(error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| flush_metadata_impl(ec); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| m_stat.second_tick(tick_interval_ms); | │ │ │ │ │ +|void posix_part_file::flush_metadata_impl(error_code& ec) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // do we need to flush the metadata? | │ │ │ │ │ +| if (m_dirty_metadata == false) return; | │ │ │ │ │ | | │ │ │ │ │ -| // -------------------------------------------------------------- | │ │ │ │ │ -| // scrape paused torrents that are auto managed | │ │ │ │ │ -|_ _ _/_/_ _(_u_n_l_e_s_s_ _t_h_e_ _s_e_s_s_i_o_n_ _i_s_ _p_a_u_s_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_4_3_1_4 |use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming connections cap | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_h_i_s_ _a_t_ _m_a_x_ _-_ _1_,_ _s_i_n_c_e_ _w_e_ _m_a_y_ _a_d_d_ _o_n_e_ _b_e_l_o_w_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee aa lloowweerr lliimmiitt tthhaann mm__sseettttiinnggss..ccoonnnneeccttiioonnss__lliimmiitt ttoo aallllooccaattee tthhee ttoo 1100%% oorr ssoo ooff ccoonnnneeccttiioonn sslloottss ffoorr iinnccoommiinngg ccoonnnneeccttiioonnss ccaapp tthhiiss aatt mmaaxx -- 11,, ssiinnccee wwee mmaayy aadddd oonnee | │ │ │ │ │ -|bbeellooww ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::44331144 ****** | │ │ │ │ │ -|// boost, which are done immediately on a tracker response. These | │ │ │ │ │ -| // connections needs to be deducted from the regular connection attempt | │ │ │ │ │ -| // quota for this tick | │ │ │ │ │ -| if (m_boost_connections > 0) | │ │ │ │ │ +| if (m_piece_map.empty()) | │ │ │ │ │ | { | │ │ │ │ │ -| if (m_boost_connections > max_connections) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_boost_connections -= max_connections; | │ │ │ │ │ -| max_connections = 0; | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| max_connections -= m_boost_connections; | │ │ │ │ │ -| m_boost_connections = 0; | │ │ │ │ │ -| } | │ │ │ │ │ +| // if we don't have any pieces left in the | │ │ │ │ │ +| // part file, remove it | │ │ │ │ │ +| std::string const p = combine_path(m_path, m_name); | │ │ │ │ │ +| remove(p, ec); | │ │ │ │ │ +| | │ │ │ │ │ +| if (ec == boost::system::errc::no_such_file_or_directory) | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // zero connections speeds are allowed, we just won't make any connections | │ │ │ │ │ -| if (max_connections <= 0) return; | │ │ │ │ │ +| auto f = open_file(open_mode::read_write, ec); | │ │ │ │ │ +| if (ec) return; | │ │ │ │ │ | | │ │ │ │ │ -|int const limit = std::min(m_settings.get_int(settings_pack::connections_limit) | │ │ │ │ │ -|- num_connections(), std::numeric_limits::max() - 1); | │ │ │ │ │ +| std::vector header(static_cast(m_header_size)); | │ │ │ │ │ | | │ │ │ │ │ -| // this logic is here to smooth out the number of new connection | │ │ │ │ │ -| // attempts over time, to prevent connecting a large number of | │ │ │ │ │ -| // sockets, wait 10 seconds, and then try again | │ │ │ │ │ -| if (m_settings.get_bool(settings_pack::smooth_connects) && max_connections > (limit+1) / 2) | │ │ │ │ │ -| max_connections = (limit + 1) / 2; | │ │ │ │ │ +| using namespace libtorrent::aux; | │ │ │ │ │ | | │ │ │ │ │ -| aux::vector& want_peers_download = m_torrent_lists[torrent_want_peers_download]; | │ │ │ │ │ -| aux::vector& want_peers_finished = m_torrent_lists[torrent_want_peers_finished]; | │ │ │ │ │ +| char* ptr = header.data(); | │ │ │ │ │ +| write_uint32(m_max_pieces, ptr); | │ │ │ │ │ +| write_uint32(m_piece_size, ptr); | │ │ │ │ │ | | │ │ │ │ │ -| // if no torrent want any peers, just return | │ │ │ │ │ -| if (want_peers_download.empty() && want_peers_finished.empty()) return; | │ │ │ │ │ +| for (piece_index_t piece(0); piece < piece_index_t(m_max_pieces); ++piece) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _a_u_t_o_ _c_o_n_s_t_ _i_ _=_ _m___p_i_e_c_e___m_a_p_._f_i_n_d_(_p_i_e_c_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t___h_a_n_d_l_e_._c_p_p_:_5_8_9_ _|_s_u_p_p_o_r_t_ _m_o_v_i_n_g_ _f_i_l_e_s_ _i_n_t_o_ _t_h_i_s_ _c_a_l_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssuuppppoorrtt mmoovviinngg ffiilleess iinnttoo tthhiiss ccaallll ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt__hhaannddllee..ccpppp::558899 ****** | │ │ │ │ │ +|auto retp = &prio; | │ │ │ │ │ +| sync_call(&torrent::piece_priorities, retp); | │ │ │ │ │ +| std::vector ret; | │ │ │ │ │ +| ret.reserve(prio.size()); | │ │ │ │ │ +| for (auto p : prio) | │ │ │ │ │ +| ret.push_back(int(static_cast(p))); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| // if we don't have any connection attempt quota, return | │ │ │ │ │ -| if (max_connections <= 0) return; | │ │ │ │ │ +| void torrent_handle::file_priority(file_index_t index, download_priority_t priority) const | │ │ │ │ │ +| { | │ │ │ │ │ +| async_call(&torrent::set_file_priority, index, priority); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| int steps_since_last_connect = 0; | │ │ │ │ │ -| int const num_torrents = int(want_peers_finished.size() + want_peers_download.size()); | │ │ │ │ │ -| for (;;) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_next_downloading_connect_torrent >= int(want_peers_download.size())) | │ │ │ │ │ -| m_next_downloading_connect_torrent = 0; | │ │ │ │ │ +| download_priority_t torrent_handle::file_priority(file_index_t index) const | │ │ │ │ │ +| { | │ │ │ │ │ +| return sync_call_ret(dont_download, &torrent::file_priority, index); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (m_next_finished_connect_torrent >= int(want_peers_finished.size())) | │ │ │ │ │ -| m_next_finished_connect_torrent = 0; | │ │ │ │ │ +|void torrent_handle::prioritize_files(std::vector const& files) const | │ │ │ │ │ +|{ | │ │ │ │ │ +| async_call(&torrent::prioritize_files | │ │ │ │ │ +| , static_cast const&>(files)); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| torrent* t = nullptr; | │ │ │ │ │ -| // there are prioritized torrents. Pick one of those | │ │ │ │ │ -|_ _ _ _w_h_i_l_e_ _(_!_m___p_r_i_o___t_o_r_r_e_n_t_s_._e_m_p_t_y_(_)_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_4_4_5_9_ _ _|_p_o_s_t_ _a_ _m_e_s_s_a_g_e_ _t_o_ _h_a_v_e_ _t_h_i_s_ _h_a_p_p_e_n_ _i_m_m_e_d_i_a_t_e_l_y_ _i_n_s_t_e_a_d_ _o_f_ _w_a_i_t_i_n_g_ _f_o_r_ _t_h_e_ _n_e_x_t_ _t_i_c_k_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ppoosstt aa mmeessssaaggee ttoo hhaavvee tthhiiss hhaappppeenn iimmmmeeddiiaatteellyy iinnsstteeaadd ooff wwaaiittiinngg ffoorr tthhee nneexxtt ttiicckk ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::44445599 ****** | │ │ │ │ │ -|continue; | │ │ │ │ │ +| std::vector torrent_handle::get_file_priorities() const | │ │ │ │ │ +| { | │ │ │ │ │ +| aux::vector ret; | │ │ │ │ │ +| auto retp = &ret; | │ │ │ │ │ +| sync_call(&torrent::file_priorities, retp); | │ │ │ │ │ +| return TORRENT_RVO(ret); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| | │ │ │ │ │ +|// ============ start deprecation =============== | │ │ │ │ │ +| | │ │ │ │ │ +| void torrent_handle::prioritize_files(std::vector const& files) const | │ │ │ │ │ +| { | │ │ │ │ │ +| aux::vector file_prio; | │ │ │ │ │ +| file_prio.reserve(files.size()); | │ │ │ │ │ +| for (auto const p : files) { | │ │ │ │ │ +| file_prio.push_back(download_priority_t(static_cast(p))); | │ │ │ │ │ +| } | │ │ │ │ │ +| async_call(&torrent::prioritize_files, file_prio); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| std::vector torrent_handle::file_priorities() const | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _a_u_x_:_:_v_e_c_t_o_r_<_d_o_w_n_l_o_a_d___p_r_i_o_r_i_t_y___t_,_ _f_i_l_e___i_n_d_e_x___t_>_ _p_r_i_o_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/ |technically, this isn't supposed to happen, but it seems to sometimes. Some of the accounting is probably wrong in certain cases | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_h_t_t_p___s_e_e_d___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_4_4_1_ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tteecchhnniiccaallllyy,, tthhiiss iissnn''tt ssuuppppoosseedd ttoo hhaappppeenn,, bbuutt iitt sseeeemmss ttoo ssoommeettiimmeess.. SSoommee ooff tthhee aaccccoouunnttiinngg iiss pprroobbaabbllyy wwrroonngg iinn cceerrttaaiinn ccaasseess ********** | │ │ │ │ │ +|****** ....//ssrrcc//hhttttpp__sseeeedd__ccoonnnneeccttiioonn..ccpppp::444411 ****** | │ │ │ │ │ +|// cut out the chunk header from the receive buffer | │ │ │ │ │ +| TORRENT_ASSERT(m_chunk_pos + m_body_start < INT_MAX); | │ │ │ │ │ +| m_recv_buffer.cut(header_size, t->block_size() + 1024, aux::numeric_cast(m_chunk_pos + m_body_start)); | │ │ │ │ │ +| recv_buffer = m_recv_buffer.get(); | │ │ │ │ │ +| recv_buffer = recv_buffer.subspan(m_body_start); | │ │ │ │ │ +| m_chunk_pos += chunk_size; | │ │ │ │ │ +| if (chunk_size == 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(m_recv_buffer.get().size() < m_chunk_pos + m_body_start + 1 | │ │ │ │ │ +| || m_recv_buffer.get()[static_cast(m_chunk_pos + m_body_start)] == 'H' | │ │ │ │ │ +| || (m_parser.chunked_encoding() | │ │ │ │ │ +| && m_recv_buffer.get()[static_cast(m_chunk_pos + m_body_start)] == '\r')); | │ │ │ │ │ +| m_chunk_pos = -1; | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (!p->is_peer_interested() | │ │ │ │ │ -| || p->is_disconnecting() | │ │ │ │ │ -| || p->is_connecting()) | │ │ │ │ │ +| int payload = int(bytes_transferred); | │ │ │ │ │ +| if (payload > m_response_left) payload = int(m_response_left); | │ │ │ │ │ +| if (payload > front_request.length) payload = front_request.length; | │ │ │ │ │ +|if (payload > outstanding_bytes()) payload = outstanding_bytes(); | │ │ │ │ │ +|received_bytes(payload, 0); | │ │ │ │ │ +| incoming_piece_fragment(payload); | │ │ │ │ │ +| m_response_left -= payload; | │ │ │ │ │ +| | │ │ │ │ │ +| if (m_parser.status_code() == 503) | │ │ │ │ │ | { | │ │ │ │ │ -| // this peer is not unchokable. So, if it's unchoked | │ │ │ │ │ -| // already, make sure to choke it. | │ │ │ │ │ -| if (p->is_choked()) | │ │ │ │ │ -| { | │ │ │ │ │ -| p->reset_choke_counters(); | │ │ │ │ │ -| continue; | │ │ │ │ │ -| } | │ │ │ │ │ -| if (pi && pi->optimistically_unchoked) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_stats_counters.inc_stats_counter(counters::num_peers_up_unchoked_optimistic, -1); | │ │ │ │ │ -| pi->optimistically_unchoked = false; | │ │ │ │ │ -| // force a new optimistic unchoke | │ │ │ │ │ -| m_optimistic_unchoke_time_scaler = 0; | │ │ │ │ │ -|} | │ │ │ │ │ -|t->choke_peer(*p); | │ │ │ │ │ -| p->reset_choke_counters(); | │ │ │ │ │ -| continue; | │ │ │ │ │ +| if (!m_parser.finished()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| int retry_time = std::atoi(std::string(recv_buffer.begin(), recv_buffer.end()).c_str()); | │ │ │ │ │ +| if (retry_time <= 0) retry_time = 60; | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| peer_log(peer_log_alert::info, "CONNECT", "retrying in %d seconds", retry_time); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| received_bytes(0, int(bytes_transferred)); | │ │ │ │ │ +| // temporarily unavailable, retry later | │ │ │ │ │ +| t->retry_web_seed(this, seconds32(retry_time)); | │ │ │ │ │ +| disconnect(error_code(m_parser.status_code(), http_category()), operation_t::bittorrent, failure); | │ │ │ │ │ +| return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| peers.push_back(p.get()); | │ │ │ │ │ +| | │ │ │ │ │ +| // we only received the header, no data | │ │ │ │ │ +| if (recv_buffer.empty()) break; | │ │ │ │ │ +| | │ │ │ │ │ +| if (recv_buffer.size() < front_request.length) break; | │ │ │ │ │ +| | │ │ │ │ │ +| // if the response is chunked, we need to receive the last | │ │ │ │ │ +| // terminating chunk and the tail headers before we can proceed | │ │ │ │ │ +|_ _ _ _i_f_ _(_m___p_a_r_s_e_r_._c_h_u_n_k_e_d___e_n_c_o_d_i_n_g_(_)_ _&_&_ _m___c_h_u_n_k___p_o_s_ _>_=_ _0_)_ _b_r_e_a_k_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_m_a_p___d_i_s_k___i_o_._c_p_p_:_5_7_8_ _ _ _|_i_n_ _t_h_e_ _f_u_t_u_r_e_,_ _p_r_o_p_a_g_a_t_e_ _e_x_c_e_p_t_i_o_n_s_ _b_a_c_k_ _t_o_ _t_h_e_ _h_a_n_d_l_e_r_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinn tthhee ffuuttuurree,, pprrooppaaggaattee eexxcceeppttiioonnss bbaacckk ttoo tthhee hhaannddlleerrss ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmmmaapp__ddiisskk__iioo..ccpppp::557788 ****** | │ │ │ │ │ +|#if DEBUG_DISK_THREAD | │ │ │ │ │ +| { | │ │ │ │ │ +| std::unique_lock l(m_job_mutex); | │ │ │ │ │ +| | │ │ │ │ │ +| DLOG("perform_job job: %s ( %s%s) piece: %d offset: %d outstanding: %d\n" | │ │ │ │ │ +| , job_action_name[j->action] | │ │ │ │ │ +| , (j->flags & mmap_disk_job::fence) ? "fence ": "" | │ │ │ │ │ +| , (j->flags & mmap_disk_job::force_copy) ? "force_copy ": "" | │ │ │ │ │ +| , static_cast(j->piece), j->d.io.offset | │ │ │ │ │ +| , j->storage ? j->storage->num_outstanding_jobs() : -1); | │ │ │ │ │ | } | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| int const allowed_upload_slots = unchoke_sort(peers | │ │ │ │ │ -| , unchoke_interval, m_settings); | │ │ │ │ │ +| std::shared_ptr storage = j->storage; | │ │ │ │ │ | | │ │ │ │ │ -| if (m_settings.get_int(settings_pack::choking_algorithm) == settings_pack::fixed_slots_choker) | │ │ │ │ │ +| TORRENT_ASSERT(static_cast(j->action) < int(job_functions.size())); | │ │ │ │ │ +| | │ │ │ │ │ +| m_stats_counters.inc_stats_counter(counters::num_running_disk_jobs, 1); | │ │ │ │ │ +| | │ │ │ │ │ +| // call disk function | │ │ │ │ │ +|status_t ret = status_t::no_error; | │ │ │ │ │ +|try | │ │ │ │ │ | { | │ │ │ │ │ -| int const upload_slots = get_int_setting(settings_pack::unchoke_slots_limit); | │ │ │ │ │ -| m_stats_counters.set_value(counters::num_unchoke_slots, upload_slots); | │ │ │ │ │ +| int const idx = static_cast(j->action); | │ │ │ │ │ +| ret = (this->*(job_functions[static_cast(idx)]))(j); | │ │ │ │ │ | } | │ │ │ │ │ -| else | │ │ │ │ │ +| catch (boost::system::system_error const& err) | │ │ │ │ │ | { | │ │ │ │ │ -| m_stats_counters.set_value(counters::num_unchoke_slots | │ │ │ │ │ -| , allowed_upload_slots); | │ │ │ │ │ +| ret = status_t::fatal_disk_error; | │ │ │ │ │ +| j->error.ec = err.code(); | │ │ │ │ │ +| j->error.operation = operation_t::exception; | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ +| catch (std::bad_alloc const&) | │ │ │ │ │ | { | │ │ │ │ │ -| session_log("RECALCULATE UNCHOKE SLOTS: [ peers: %d " | │ │ │ │ │ -| "eligible-peers: %d" | │ │ │ │ │ -| " allowed-slots: %d ]" | │ │ │ │ │ -| , int(m_connections.size()) | │ │ │ │ │ -|_ _ _ _ _,_ _i_n_t_(_p_e_e_r_s_._s_i_z_e_(_)_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -| | |it might be a nice feature here to limit the number of torrents to send in a single update. By just posting the first n torrents, | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_4_7_8_6 |they would nicely be round-robined because the torrent lists are always pushed back. Perhaps the status_update_alert could even have| │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_a_ _f_i_x_e_d_ _a_r_r_a_y_ _o_f_ _n_ _e_n_t_r_i_e_s_ _r_a_t_h_e_r_ _t_h_a_n_ _a_ _v_e_c_t_o_r_,_ _t_o_ _f_u_r_t_h_e_r_ _i_m_p_r_o_v_e_ _m_e_m_o_r_y_ _l_o_c_a_l_i_t_y_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt mmiigghhtt bbee aa nniiccee ffeeaattuurree hheerree ttoo lliimmiitt tthhee nnuummbbeerr ooff ttoorrrreennttss ttoo sseenndd iinn aa ssiinnggllee uuppddaattee.. BByy jjuusstt ppoossttiinngg tthhee ffiirrsstt nn ttoorrrreennttss,, tthheeyy wwoouulldd nniicceellyy bbee rroouunndd--rroobbiinneedd | │ │ │ │ │ -|bbeeccaauussee tthhee ttoorrrreenntt lliissttss aarree aallwwaayyss ppuusshheedd bbaacckk.. PPeerrhhaappss tthhee ssttaattuuss__uuppddaattee__aalleerrtt ccoouulldd eevveenn hhaavvee aa ffiixxeedd aarrrraayy ooff nn eennttrriieess rraatthheerr tthhaann aa vveeccttoorr,, ttoo ffuurrtthheerr iimmpprroovvee mmeemmoorryy | │ │ │ │ │ -|llooccaalliittyy.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::44778866 ****** | │ │ │ │ │ -|t->status(&st, flags); | │ │ │ │ │ +| ret = status_t::fatal_disk_error; | │ │ │ │ │ +| j->error.ec = errors::no_memory; | │ │ │ │ │ +| j->error.operation = operation_t::exception; | │ │ │ │ │ +| } | │ │ │ │ │ +| catch (std::exception const&) | │ │ │ │ │ +| { | │ │ │ │ │ +| ret = status_t::fatal_disk_error; | │ │ │ │ │ +| j->error.ec = boost::asio::error::fault; | │ │ │ │ │ +| j->error.operation = operation_t::exception; | │ │ │ │ │ | } | │ │ │ │ │ +| | │ │ │ │ │ +| // note that -2 errors are OK | │ │ │ │ │ +| TORRENT_ASSERT(ret != status_t::fatal_disk_error | │ │ │ │ │ +| || (j->error.ec && j->error.operation != operation_t::unknown)); | │ │ │ │ │ +| | │ │ │ │ │ +|_ _ _m___s_t_a_t_s___c_o_u_n_t_e_r_s_._i_n_c___s_t_a_t_s___c_o_u_n_t_e_r_(_c_o_u_n_t_e_r_s_:_:_n_u_m___r_u_n_n_i_n_g___d_i_s_k___j_o_b_s_,_ _-_1_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_m_m_a_p___d_i_s_k___i_o_._c_p_p_:_1_0_1_7 |this is potentially very expensive. One way to solve it would be to have a fence for just this one piece. but it hardly seems worth | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_h_e_ _c_o_m_p_l_e_x_i_t_y_ _a_n_d_ _c_o_s_t_ _j_u_s_t_ _f_o_r_ _t_h_e_ _e_d_g_e_ _c_a_s_e_ _o_f_ _r_e_c_e_i_v_i_n_g_ _a_ _c_o_r_r_u_p_t_ _p_i_e_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss iiss ppootteennttiiaallllyy vveerryy eexxppeennssiivvee.. OOnnee wwaayy ttoo ssoollvvee iitt wwoouulldd bbee ttoo hhaavvee aa ffeennccee ffoorr jjuusstt tthhiiss oonnee ppiieeccee.. bbuutt iitt hhaarrddllyy sseeeemmss wwoorrtthh tthhee ccoommpplleexxiittyy aanndd ccoosstt jjuusstt ffoorr tthhee | │ │ │ │ │ +|eeddggee ccaassee ooff rreecceeiivviinngg aa ccoorrrruupptt ppiieeccee ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmmmaapp__ddiisskk__iioo..ccpppp::11001177 ****** | │ │ │ │ │ +|aux::mmap_disk_job* j = m_job_pool.allocate_job(aux::job_action_t::file_priority); | │ │ │ │ │ +| j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ +| j->argument = std::move(prios); | │ │ │ │ │ +| j->callback = std::move(handler); | │ │ │ │ │ +| | │ │ │ │ │ +| add_fence_job(j); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::post_torrent_updates(status_flags_t const flags) | │ │ │ │ │ +| void mmap_disk_io::async_clear_piece(storage_index_t const storage | │ │ │ │ │ +| , piece_index_t const index, std::function handler) | │ │ │ │ │ | { | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ +| aux::mmap_disk_job* j = m_job_pool.allocate_job(aux::job_action_t::clear_piece); | │ │ │ │ │ +| j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ +| j->piece = index; | │ │ │ │ │ +| j->callback = std::move(handler); | │ │ │ │ │ | | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| // regular jobs are not guaranteed to be executed in-order | │ │ │ │ │ +| // since clear piece must guarantee that all write jobs that | │ │ │ │ │ +| // have been issued finish before the clear piece job completes | │ │ │ │ │ | | │ │ │ │ │ -| std::vector& state_updates | │ │ │ │ │ -| = m_torrent_lists[aux::session_impl::torrent_state_updates]; | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_m_m_a_p___d_i_s_k___i_o_._c_p_p_:_1_0_2_2 |Perhaps the job queue could be traversed and all jobs for this piece could be cancelled. If there are no threads currently writing | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_o_ _t_h_i_s_ _p_i_e_c_e_,_ _w_e_ _c_o_u_l_d_ _s_k_i_p_ _t_h_e_ _f_e_n_c_e_ _a_l_t_o_g_e_t_h_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** PPeerrhhaappss tthhee jjoobb qquueeuuee ccoouulldd bbee ttrraavveerrsseedd aanndd aallll jjoobbss ffoorr tthhiiss ppiieeccee ccoouulldd bbee ccaanncceelllleedd.. IIff tthheerree aarree nnoo tthhrreeaaddss ccuurrrreennttllyy wwrriittiinngg ttoo tthhiiss ppiieeccee,, wwee ccoouulldd sskkiipp tthhee ffeennccee| │ │ │ │ │ +|aallttooggeetthheerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmmmaapp__ddiisskk__iioo..ccpppp::11002222 ****** | │ │ │ │ │ +|j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ +| j->argument = std::move(prios); | │ │ │ │ │ +| j->callback = std::move(handler); | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -| m_posting_torrent_updates = true; | │ │ │ │ │ -|#endif | │ │ │ │ │ +| add_fence_job(j); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| std::vector status; | │ │ │ │ │ -| status.reserve(state_updates.size()); | │ │ │ │ │ +| void mmap_disk_io::async_clear_piece(storage_index_t const storage | │ │ │ │ │ +| , piece_index_t const index, std::function handler) | │ │ │ │ │ +| { | │ │ │ │ │ +| aux::mmap_disk_job* j = m_job_pool.allocate_job(aux::job_action_t::clear_piece); | │ │ │ │ │ +| j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ +| j->piece = index; | │ │ │ │ │ +| j->callback = std::move(handler); | │ │ │ │ │ | | │ │ │ │ │ -|for (auto& t : state_updates) | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(t->m_links[aux::session_impl::torrent_state_updates].in_list()); | │ │ │ │ │ -| status.emplace_back(); | │ │ │ │ │ -| // querying accurate download counters may require | │ │ │ │ │ -| // the torrent to be loaded. Loading a torrent, and evicting another | │ │ │ │ │ -| // one will lead to calling state_updated(), which screws with | │ │ │ │ │ -| // this list while we're working on it, and break things | │ │ │ │ │ -| t->status(&status.back(), flags); | │ │ │ │ │ -| t->clear_in_state_update(); | │ │ │ │ │ -| } | │ │ │ │ │ -| state_updates.clear(); | │ │ │ │ │ +| // regular jobs are not guaranteed to be executed in-order | │ │ │ │ │ +| // since clear piece must guarantee that all write jobs that | │ │ │ │ │ +| // have been issued finish before the clear piece job completes | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -| m_posting_torrent_updates = false; | │ │ │ │ │ -|#endif | │ │ │ │ │ | | │ │ │ │ │ -| m_alerts.emplace_alert(std::move(status)); | │ │ │ │ │ -| } | │ │ │ │ │ +|add_fence_job(j); | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| void session_impl::post_session_stats() | │ │ │ │ │ +| status_t mmap_disk_io::do_hash(aux::mmap_disk_job* j) | │ │ │ │ │ | { | │ │ │ │ │ -| if (!m_posted_stats_header) | │ │ │ │ │ +| // we're not using a cache. This is the simple path | │ │ │ │ │ +| // just read straight from the file | │ │ │ │ │ +| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +| | │ │ │ │ │ +| bool const v1 = bool(j->flags & disk_interface::v1_hash); | │ │ │ │ │ +| bool const v2 = !j->d.h.block_hashes.empty(); | │ │ │ │ │ +| | │ │ │ │ │ +| int const piece_size = v1 ? j->storage->files().piece_size(j->piece) : 0; | │ │ │ │ │ +| int const piece_size2 = v2 ? j->storage->files().piece_size2(j->piece) : 0; | │ │ │ │ │ +| int const blocks_in_piece = v1 ? (piece_size + default_block_size - 1) / default_block_size : 0; | │ │ │ │ │ +| int const blocks_in_piece2 = v2 ? j->storage->files().blocks_in_piece2(j->piece) : 0; | │ │ │ │ │ +| aux::open_mode_t const file_mode = file_mode_for_job(j); | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(!v2 || int(j->d.h.block_hashes.size()) >= blocks_in_piece2); | │ │ │ │ │ +| TORRENT_ASSERT(v1 || v2); | │ │ │ │ │ +| | │ │ │ │ │ +| hasher h; | │ │ │ │ │ +| int ret = 0; | │ │ │ │ │ +| int offset = 0; | │ │ │ │ │ +| int const blocks_to_read = std::max(blocks_in_piece, blocks_in_piece2); | │ │ │ │ │ +| time_point const start_time = clock_type::now(); | │ │ │ │ │ +| for (int i = 0; i < blocks_to_read; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| m_posted_stats_header = true; | │ │ │ │ │ -| m_alerts.emplace_alert(); | │ │ │ │ │ +| bool const v2_block = i < blocks_in_piece2; | │ │ │ │ │ +| | │ │ │ │ │ +|_ _ _ _D_L_O_G_(_"_d_o___h_a_s_h_:_ _r_e_a_d_i_n_g_ _(_p_i_e_c_e_:_ _%_d_ _b_l_o_c_k_:_ _%_d_)_\_n_"_,_ _i_n_t_(_j_-_>_p_i_e_c_e_)_,_ _i_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_c_h_o_k_e_r_._c_p_p_:_2_5_8_ _ _ _ _ _ _ _ _ _|_m_a_k_e_ _c_o_n_f_i_g_u_r_a_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmaakkee ccoonnffiigguurraabbllee ********** | │ │ │ │ │ +|****** ....//ssrrcc//cchhookkeerr..ccpppp::225588 ****** | │ │ │ │ │ +|// first reset the number of unchoke slots, because we'll calculate | │ │ │ │ │ +| // it purely based on the current state of our peers. | │ │ │ │ │ +| upload_slots = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| int rate_threshold = sett.get_int(settings_pack::rate_choker_initial_threshold); | │ │ │ │ │ +| | │ │ │ │ │ +| std::sort(peers.begin(), peers.end() | │ │ │ │ │ +| , [](peer_connection const* lhs, peer_connection const* rhs) | │ │ │ │ │ +| { return upload_rate_compare(lhs, rhs); }); | │ │ │ │ │ +| | │ │ │ │ │ +| for (auto const* p : peers) | │ │ │ │ │ +| { | │ │ │ │ │ +| int const rate = int(p->uploaded_in_last_round() | │ │ │ │ │ +| * 1000 / total_milliseconds(unchoke_interval)); | │ │ │ │ │ +| | │ │ │ │ │ +| // always have at least 1 unchoke slot | │ │ │ │ │ +| if (rate < rate_threshold) break; | │ │ │ │ │ +| | │ │ │ │ │ +| ++upload_slots; | │ │ │ │ │ +| | │ │ │ │ │ +|rate_threshold += 2048; | │ │ │ │ │ +|} | │ │ │ │ │ +| ++upload_slots; | │ │ │ │ │ | } | │ │ │ │ │ -| m_disk_thread->update_stats_counters(m_stats_counters); | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -|_ _ _i_f_ _(_m___d_h_t_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_1_6_1_ _ _|_f_a_c_t_o_r_ _o_u_t_ _t_h_i_s_ _l_o_g_i_c_ _i_n_t_o_ _a_ _s_e_p_a_r_a_t_e_ _f_u_n_c_t_i_o_n_ _f_o_r_ _u_n_i_t_ _t_e_s_t_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ffaaccttoorr oouutt tthhiiss llooggiicc iinnttoo aa sseeppaarraattee ffuunnccttiioonn ffoorr uunniitt tteessttiinngg ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55116611 ****** | │ │ │ │ │ -|if (m_settings.get_int(settings_pack::outgoing_port) > 0) | │ │ │ │ │ +| // sorts the peers that are eligible for unchoke by download rate and | │ │ │ │ │ +| // secondary by total upload. The reason for this is, if all torrents are | │ │ │ │ │ +| // being seeded, the download rate will be 0, and the peers we have sent | │ │ │ │ │ +| // the least to should be unchoked | │ │ │ │ │ +| | │ │ │ │ │ +| // we use partial sort here, because we only care about the top | │ │ │ │ │ +| // upload_slots peers. | │ │ │ │ │ +| | │ │ │ │ │ +| int const slots = std::min(upload_slots, int(peers.size())); | │ │ │ │ │ +| | │ │ │ │ │ +| if (sett.get_int(settings_pack::seed_choking_algorithm) | │ │ │ │ │ +| == settings_pack::round_robin) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifdef TORRENT_WINDOWS | │ │ │ │ │ -| s.set_option(exclusive_address_use(true), ec); | │ │ │ │ │ -|#else | │ │ │ │ │ -| s.set_option(tcp::acceptor::reuse_address(true), ec); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| // ignore errors because the underlying socket may not | │ │ │ │ │ -| // be opened yet. This happens when we're routing through | │ │ │ │ │ -| // a proxy. In that case, we don't yet know the address of | │ │ │ │ │ -| // the proxy server, and more importantly, we don't know | │ │ │ │ │ -| // the address family of its address. This means we can't | │ │ │ │ │ -| // open the socket yet. The socks abstraction layer defers | │ │ │ │ │ -| // opening it. | │ │ │ │ │ -| ec.clear(); | │ │ │ │ │ -| bind_ep.port(std::uint16_t(next_port())); | │ │ │ │ │ +| int const pieces = sett.get_int(settings_pack::seeding_piece_quota); | │ │ │ │ │ +| | │ │ │ │ │ +| std::nth_element(peers.begin(), peers.begin() | │ │ │ │ │ +| + slots, peers.end() | │ │ │ │ │ +| , [pieces](peer_connection const* lhs, peer_connection const* rhs) | │ │ │ │ │ +| { return unchoke_compare_rr(lhs, rhs, pieces); }); | │ │ │ │ │ | } | │ │ │ │ │ +| else if (sett.get_int(settings_pack::seed_choking_algorithm) | │ │ │ │ │ +| == settings_pack::fastest_upload) | │ │ │ │ │ +| { | │ │ │ │ │ +| std::nth_element(peers.begin(), peers.begin() | │ │ │ │ │ +| + slots, peers.end() | │ │ │ │ │ +|_ _ _ _ _,_ _[_]_(_p_e_e_r___c_o_n_n_e_c_t_i_o_n_ _c_o_n_s_t_*_ _l_h_s_,_ _p_e_e_r___c_o_n_n_e_c_t_i_o_n_ _c_o_n_s_t_*_ _r_h_s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_1_1_0_ _ _ _ _|_i_n_ _C_+_+_2_0_,_ _u_s_e_ _s_t_d_:_:_i_d_e_n_t_i_t_y_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinn CC++++2200,, uussee ssttdd::::iiddeennttiittyy ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::111100 ****** | │ │ │ │ │ +|allocate_full(); | │ │ │ │ │ | | │ │ │ │ │ -| if (is_utp(s)) | │ │ │ │ │ +| merkle_validate_copy(t, m_tree, root(), m_block_verified); | │ │ │ │ │ +| | │ │ │ │ │ +| load_verified_bits(verified); | │ │ │ │ │ +| | │ │ │ │ │ +| optimize_storage(); | │ │ │ │ │ +| optimize_storage_piece_layer(); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void merkle_tree::clear() | │ │ │ │ │ +| { | │ │ │ │ │ +| m_tree.clear(); | │ │ │ │ │ +| m_tree.shrink_to_fit(); | │ │ │ │ │ +| m_block_verified.clear(); | │ │ │ │ │ +| m_mode = mode_t::empty_tree; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|namespace { | │ │ │ │ │ +| | │ │ │ │ │ +|struct identity | │ │ │ │ │ +|{ | │ │ │ │ │ +| bool operator()(bool b) const { return b; } | │ │ │ │ │ +| }; | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +| void merkle_tree::load_sparse_tree(span t | │ │ │ │ │ +| , std::vector const& mask | │ │ │ │ │ +| , std::vector const& verified) | │ │ │ │ │ +| { | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| TORRENT_ASSERT(mask.size() == size()); | │ │ │ │ │ +| if (size() != mask.size()) return; | │ │ │ │ │ +| | │ │ │ │ │ +| int const first_block = block_layer_start(); | │ │ │ │ │ +| int const end_block = first_block + m_num_blocks; | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(first_block < int(mask.size())); | │ │ │ │ │ +| TORRENT_ASSERT(end_block <= int(mask.size())); | │ │ │ │ │ +| | │ │ │ │ │ +| // if the mask covers all blocks, go straight to block_layer | │ │ │ │ │ +| // mode, and validate | │ │ │ │ │ +| if (std::all_of(mask.begin() + first_block, mask.begin() + end_block, identity())) | │ │ │ │ │ | { | │ │ │ │ │ +| // the index in t that points to first_block | │ │ │ │ │ +| auto const block_index = std::count_if(mask.begin(), mask.begin() + first_block, identity()); | │ │ │ │ │ | | │ │ │ │ │ -|utp_socket_impl* impl = nullptr; | │ │ │ │ │ -| transport ssl = transport::plaintext; | │ │ │ │ │ -|#if TORRENT_USE_SSL | │ │ │ │ │ -| if (boost::get>(&s) != nullptr) | │ │ │ │ │ +| // discrepancy | │ │ │ │ │ +| if (t.size() < block_index + m_num_blocks) | │ │ │ │ │ +|_ _ _ _ _r_e_t_u_r_n_ _c_l_e_a_r_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_3_1_9_ _ _ _ _|_t_h_i_s_ _c_a_n_ _b_e_ _o_p_t_i_m_i_z_e_d_ _b_y_ _u_s_i_n_g_ _m___t_r_e_e_ _a_s_ _s_t_o_r_a_g_e_ _t_o_ _f_i_l_l_ _t_h_i_s_ _t_r_e_e_ _i_n_t_o_,_ _a_n_d_ _t_h_e_n_ _c_l_e_a_r_ _i_t_ _i_f_ _t_h_e_ _h_a_s_h_e_s_ _f_a_i_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ccaann bbee ooppttiimmiizzeedd bbyy uussiinngg mm__ttrreeee aass ssttoorraaggee ttoo ffiillll tthhiiss ttrreeee iinnttoo,, aanndd tthheenn cclleeaarr iitt iiff tthhee hhaasshheess ffaaiill ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::331199 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| | │ │ │ │ │ +| // as we set the hashes of interior nodes, we may be able to validate | │ │ │ │ │ +| // block hashes that we had since earlier. Any blocks that can be | │ │ │ │ │ +| // validated, and failed, are added to this list | │ │ │ │ │ +| add_hashes_result_t ret; | │ │ │ │ │ +| | │ │ │ │ │ +| // we already have all hashes | │ │ │ │ │ +| if (m_mode == mode_t::block_layer) | │ │ │ │ │ +| { | │ │ │ │ │ +| // since we're already on the block layer mode, we have the whole | │ │ │ │ │ +| // tree, and we've already reported any pieces as passing that may | │ │ │ │ │ +| // have existed in the tree when we completed it. At this point no | │ │ │ │ │ +| // more pieces should be reported as passed | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| allocate_full(); | │ │ │ │ │ +| | │ │ │ │ │ +|int const leaf_count = merkle_num_leafs(int(hashes.size())); | │ │ │ │ │ +|aux::vector tree(merkle_num_nodes(leaf_count)); | │ │ │ │ │ +| std::copy(hashes.begin(), hashes.end(), tree.end() - leaf_count); | │ │ │ │ │ +| | │ │ │ │ │ +| // the end of a file is a special case, we may need to pad the leaf layer | │ │ │ │ │ +| if (leaf_count > hashes.size()) | │ │ │ │ │ +| { | │ │ │ │ │ +| int const leaf_layer_size = num_leafs(); | │ │ │ │ │ +| // assuming uncle_hashes lead all the way to the root, they tell us | │ │ │ │ │ +| // how many layers down we are | │ │ │ │ │ +| int const insert_layer_size = leaf_count << uncle_hashes.size(); | │ │ │ │ │ +| if (leaf_layer_size != insert_layer_size) | │ │ │ │ │ | { | │ │ │ │ │ -| impl = boost::get>(s).next_layer().get_impl(); | │ │ │ │ │ -| ssl = transport::ssl; | │ │ │ │ │ +| sha256_hash const pad_hash = merkle_pad(leaf_layer_size, insert_layer_size); | │ │ │ │ │ +| for (int i = int(hashes.size()); i < leaf_count; ++i) | │ │ │ │ │ +| tree[tree.end_index() - leaf_count + i] = pad_hash; | │ │ │ │ │ | } | │ │ │ │ │ -| else | │ │ │ │ │ -|#endif | │ │ │ │ │ -| impl = boost::get(s).get_impl(); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| std::vector> with_gateways; | │ │ │ │ │ -| std::shared_ptr match; | │ │ │ │ │ -| for (auto& ls : m_listen_sockets) | │ │ │ │ │ +| merkle_fill_tree(tree, leaf_count); | │ │ │ │ │ +| | │ │ │ │ │ +| int const base_num_layers = merkle_num_layers(leaf_count); | │ │ │ │ │ +| | │ │ │ │ │ +| // this is the index of the node where we'll insert the root of the | │ │ │ │ │ +| // subtree (tree). It's also the hash the uncle_hashes are here to prove | │ │ │ │ │ +| // is valid. | │ │ │ │ │ +| int const insert_root_idx = dest_start_idx >> base_num_layers; | │ │ │ │ │ +| | │ │ │ │ │ +| // start with validating the proofs, and inserting them as we go. | │ │ │ │ │ +| if (!merkle_validate_and_insert_proofs(m_tree, insert_root_idx, tree[0], uncle_hashes)) | │ │ │ │ │ +|_ _ _ _r_e_t_u_r_n_ _{_}_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_3_6_7_ _ _ _ _|_a_ _p_i_e_c_e_ _o_u_t_s_i_d_e_ _o_f_ _t_h_i_s_ _r_a_n_g_e_ _m_a_y_ _a_l_s_o_ _f_a_i_l_,_ _i_f_ _o_n_e_ _o_f_ _t_h_e_ _u_n_c_l_e_ _h_a_s_h_e_s_ _i_s_ _a_t_ _t_h_e_ _l_a_y_e_r_ _r_i_g_h_t_ _a_b_o_v_e_ _t_h_e_ _b_l_o_c_k_ _h_a_s_h_e_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aa ppiieeccee oouuttssiiddee ooff tthhiiss rraannggee mmaayy aallssoo ffaaiill,, iiff oonnee ooff tthhee uunnccllee hhaasshheess iiss aatt tthhee llaayyeerr rriigghhtt aabboovvee tthhee bblloocckk hhaasshheess ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::336677 ****** | │ │ │ │ │ +|int const insert_root_idx = dest_start_idx >> base_num_layers; | │ │ │ │ │ +| | │ │ │ │ │ +| // start with validating the proofs, and inserting them as we go. | │ │ │ │ │ +| if (!merkle_validate_and_insert_proofs(m_tree, insert_root_idx, tree[0], uncle_hashes)) | │ │ │ │ │ +| return {}; | │ │ │ │ │ +| | │ │ │ │ │ +| // first fill in the subtree of known hashes from the base layer | │ │ │ │ │ +| auto const num_leafs = merkle_num_leafs(m_num_blocks); | │ │ │ │ │ +| auto const first_leaf = merkle_first_leaf(num_leafs); | │ │ │ │ │ +| | │ │ │ │ │ +| // this is the start of the leaf layer of "tree". We'll use this | │ │ │ │ │ +| // variable to step upwards towards the root | │ │ │ │ │ +| int source_cursor = int(tree.size()) - leaf_count; | │ │ │ │ │ +| // the running index in the loop | │ │ │ │ │ +| int dest_cursor = dest_start_idx; | │ │ │ │ │ +| | │ │ │ │ │ +| // the number of tree levels in a piece hash. 0 means the block layer is | │ │ │ │ │ +| // the same as the piece layer | │ │ │ │ │ +| int const base = piece_levels(); | │ │ │ │ │ +| | │ │ │ │ │ +|for (int layer_size = leaf_count; layer_size != 0; layer_size /= 2) | │ │ │ │ │ +|{ | │ │ │ │ │ +| for (int i = 0; i < layer_size; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| // this is almost, but not quite, like can_route() | │ │ │ │ │ -| if (!(ls->flags & listen_socket_t::proxy) | │ │ │ │ │ -| && is_v4(ls->local_endpoint) != remote_address.is_v4()) | │ │ │ │ │ +| int const dst_idx = dest_cursor + i; | │ │ │ │ │ +| int const src_idx = source_cursor + i; | │ │ │ │ │ +| if (has_node(dst_idx)) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (m_tree[dst_idx] != tree[src_idx]) | │ │ │ │ │ +| { | │ │ │ │ │ +| // this must be a block hash because inner nodes are not filled in until | │ │ │ │ │ +| // they can be verified. This assert ensures we're at the | │ │ │ │ │ +| // leaf layer of the file tree | │ │ │ │ │ +| TORRENT_ASSERT(dst_idx >= first_leaf); | │ │ │ │ │ +| | │ │ │ │ │ +| int const pos = dst_idx - first_leaf; | │ │ │ │ │ +| auto const piece = piece_index_t{pos >> m_blocks_per_piece_log} + file_piece_offset; | │ │ │ │ │ +| int const block = pos & ((1 << m_blocks_per_piece_log) - 1); | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(pos < m_num_blocks); | │ │ │ │ │ +| if (!ret.failed.empty() && ret.failed.back().first == piece) | │ │ │ │ │ +| ret.failed.back().second.push_back(block); | │ │ │ │ │ +| else | │ │ │ │ │ +| ret.failed.emplace_back(piece, std::vector{block}); | │ │ │ │ │ +| | │ │ │ │ │ +| // now that this hash has been reported as failing, we | │ │ │ │ │ +| // can clear it. This will prevent it from being | │ │ │ │ │ +| // reported as failing again. | │ │ │ │ │ +| m_tree[dst_idx].clear(); | │ │ │ │ │ +| } | │ │ │ │ │ +|_ _ _ _ _ _e_l_s_e_ _i_f_ _(_d_s_t___i_d_x_ _>_=_ _f_i_r_s_t___l_e_a_f_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_4_4_7 |instead of overwriting the root and comparing it against hashes[], write a functions that *validates* a tree by just filling it up | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_o_ _t_h_e_ _l_e_v_e_l_ _b_e_l_o_w_ _t_h_e_ _r_o_o_t_ _a_n_d_ _t_h_e_n_ _v_a_l_i_d_a_t_e_s_ _i_t_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinnsstteeaadd ooff oovveerrwwrriittiinngg tthhee rroooott aanndd ccoommppaarriinngg iitt aaggaaiinnsstt hhaasshheess[[]],, wwrriittee aa ffuunnccttiioonnss tthhaatt **vvaalliiddaatteess** aa ttrreeee bbyy jjuusstt ffiilllliinngg iitt uupp ttoo tthhee lleevveell bbeellooww tthhee rroooott aanndd tthheenn | │ │ │ │ │ +|vvaalliiddaatteess iitt.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::444477 ****** | │ │ │ │ │ +|&& dest_start_idx < first_piece_idx + num_pieces()) | │ │ │ │ │ +| { | │ │ │ │ │ +| int const blocks_in_piece = 1 << base; | │ │ │ │ │ +| | │ │ │ │ │ +| // it may now be possible to verify the hashes of previously received blocks | │ │ │ │ │ +| // try to verify as many child nodes of the received hashes as possible | │ │ │ │ │ +| for (int i = 0; i < int(hashes.size()); ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| int const piece = dest_start_idx + i; | │ │ │ │ │ +| if (piece - first_piece_idx >= num_pieces()) | │ │ │ │ │ +| break; | │ │ │ │ │ +| // the first block in this piece | │ │ │ │ │ +| int const block_idx = merkle_get_first_child(piece, base); | │ │ │ │ │ +| | │ │ │ │ │ +| int const block_end_idx = std::min(block_idx + blocks_in_piece, first_leaf + m_num_blocks); | │ │ │ │ │ +| if (std::any_of(m_tree.begin() + block_idx | │ │ │ │ │ +| , m_tree.begin() + block_end_idx | │ │ │ │ │ +| , [](sha256_hash const& h) { return h.is_all_zeros(); })) | │ │ │ │ │ | continue; | │ │ │ │ │ -| if (ls->ssl != ssl) continue; | │ │ │ │ │ -| if (!(ls->flags & listen_socket_t::local_network)) | │ │ │ │ │ -| with_gateways.push_back(ls); | │ │ │ │ │ | | │ │ │ │ │ -| if (ls->flags & listen_socket_t::proxy | │ │ │ │ │ -| || match_addr_mask(ls->local_endpoint.address(), remote_address, ls->netmask)) | │ │ │ │ │ +|merkle_fill_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ +|if (m_tree[piece] != hashes[i]) | │ │ │ │ │ | { | │ │ │ │ │ -| // is this better than the previous match? | │ │ │ │ │ -| match = ls; | │ │ │ │ │ -|_ _ _ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_8_8_0_ _ _|_r_e_f_a_c_t_o_r_,_ _m_o_v_e_ _t_h_e_ _s_t_o_r_a_g_e_ _t_o_ _d_h_t___t_r_a_c_k_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** rreeffaaccttoorr,, mmoovvee tthhee ssttoorraaggee ttoo ddhhtt__ttrraacckkeerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55888800 ****** | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| session_log("not starting DHT, outstanding router lookups: %d" | │ │ │ │ │ -| , m_outstanding_router_lookups); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ +| merkle_clear_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ +| // write back the correct hash | │ │ │ │ │ +| m_tree[piece] = hashes[i]; | │ │ │ │ │ +| TORRENT_ASSERT(blocks_in_piece == blocks_per_piece()); | │ │ │ │ │ | | │ │ │ │ │ -| if (m_abort) | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| session_log("not starting DHT, aborting"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| return; | │ │ │ │ │ +| // an empty blocks vector indicates that we don't have the | │ │ │ │ │ +| // block hashes, and we can't know which block failed | │ │ │ │ │ +| // this will cause the block hashes to be requested | │ │ │ │ │ +| ret.failed.emplace_back(piece_index_t{piece - first_piece_idx} + file_piece_offset | │ │ │ │ │ +| , std::vector()); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| ret.passed.push_back(piece_index_t{piece - first_piece_idx} + file_piece_offset); | │ │ │ │ │ +| // record that these block hashes are correct! | │ │ │ │ │ +| int const leafs_start = block_idx - block_layer_start(); | │ │ │ │ │ +|_ _ _ _ _ _i_n_t_ _c_o_n_s_t_ _l_e_a_f_s___e_n_d_ _=_ _s_t_d_:_:_m_i_n_(_m___n_u_m___b_l_o_c_k_s_,_ _l_e_a_f_s___s_t_a_r_t_ _+_ _b_l_o_c_k_s___i_n___p_i_e_c_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_4_7_1_ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _d_o_n_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_l_y_ _i_f_ _b_i_t_f_i_e_l_d_ _h_a_d_ _a_ _f_u_n_c_t_i_o_n_ _t_o_ _s_e_t_ _a_ _r_a_n_g_e_ _o_f_ _b_i_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ccoouulldd bbee ddoonnee mmoorree eeffffiicciieennttllyy iiff bbiittffiieelldd hhaadd aa ffuunnccttiioonn ttoo sseett aa rraannggee ooff bbiittss ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::447711 ****** | │ │ │ │ │ +|merkle_fill_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ +| if (m_tree[piece] != hashes[i]) | │ │ │ │ │ +| { | │ │ │ │ │ +| merkle_clear_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ +| // write back the correct hash | │ │ │ │ │ +| m_tree[piece] = hashes[i]; | │ │ │ │ │ +| TORRENT_ASSERT(blocks_in_piece == blocks_per_piece()); | │ │ │ │ │ +| | │ │ │ │ │ +| // an empty blocks vector indicates that we don't have the | │ │ │ │ │ +| // block hashes, and we can't know which block failed | │ │ │ │ │ +| // this will cause the block hashes to be requested | │ │ │ │ │ +| ret.failed.emplace_back(piece_index_t{piece - first_piece_idx} + file_piece_offset | │ │ │ │ │ +| , std::vector()); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| ret.passed.push_back(piece_index_t{piece - first_piece_idx} + file_piece_offset); | │ │ │ │ │ +| // record that these block hashes are correct! | │ │ │ │ │ +| int const leafs_start = block_idx - block_layer_start(); | │ │ │ │ │ +| int const leafs_end = std::min(m_num_blocks, leafs_start + blocks_in_piece); | │ │ │ │ │ +|for (int k = leafs_start; k < leafs_end; ++k) | │ │ │ │ │ +|m_block_verified.set_bit(k); | │ │ │ │ │ +| } | │ │ │ │ │ +| TORRENT_ASSERT((piece - first_piece_idx) >= 0); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| session_log("starting DHT, running: %s, router lookups: %d" | │ │ │ │ │ -| , m_dht ? "true" : "false", m_outstanding_router_lookups); | │ │ │ │ │ +| optimize_storage(); | │ │ │ │ │ +| | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| std::tuple merkle_tree::set_block(int const block_index | │ │ │ │ │ +| , sha256_hash const& h) | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ |#endif | │ │ │ │ │ +| TORRENT_ASSERT(block_index < m_num_blocks); | │ │ │ │ │ | | │ │ │ │ │ -|m_dht_storage = m_dht_storage_constructor(m_settings); | │ │ │ │ │ -|m_dht = std::make_shared( | │ │ │ │ │ -| static_cast(this) | │ │ │ │ │ -| , m_io_context | │ │ │ │ │ -| , [this](aux::listen_socket_handle const& sock | │ │ │ │ │ -| , udp::endpoint const& ep | │ │ │ │ │ -| , span p | │ │ │ │ │ -| , error_code& ec | │ │ │ │ │ -| , udp_send_flags_t const flags) | │ │ │ │ │ -| { send_udp_packet_listen(sock, ep, p, ec, flags); } | │ │ │ │ │ -| , m_settings | │ │ │ │ │ -| , m_stats_counters | │ │ │ │ │ -| , *m_dht_storage | │ │ │ │ │ -| , std::move(m_dht_state)); | │ │ │ │ │ +| auto const num_leafs = merkle_num_leafs(m_num_blocks); | │ │ │ │ │ +| auto const first_leaf = merkle_first_leaf(num_leafs); | │ │ │ │ │ +| auto const block_tree_index = first_leaf + block_index; | │ │ │ │ │ | | │ │ │ │ │ -| for (auto& s : m_listen_sockets) | │ │ │ │ │ +| if (blocks_verified(block_index, 1)) | │ │ │ │ │ | { | │ │ │ │ │ -| if (s->ssl != transport::ssl | │ │ │ │ │ -| && !(s->flags & listen_socket_t::local_network)) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_dht->new_socket(s); | │ │ │ │ │ -| } | │ │ │ │ │ +| // if this blocks's hash is already known, check the passed-in hash against it | │ │ │ │ │ +| if (compare_node(block_tree_index, h)) | │ │ │ │ │ +| return std::make_tuple(set_block_result::ok, block_index, 1); | │ │ │ │ │ +| else | │ │ │ │ │ +|_ _ _ _ _r_e_t_u_r_n_ _s_t_d_:_:_m_a_k_e___t_u_p_l_e_(_s_e_t___b_l_o_c_k___r_e_s_u_l_t_:_:_b_l_o_c_k___h_a_s_h___f_a_i_l_e_d_,_ _b_l_o_c_k___i_n_d_e_x_,_ _1_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_5_1_4_ _ _ _ _|_u_s_e_ _s_t_r_u_c_t_u_r_e_d_ _b_i_n_d_i_n_g_ _i_n_ _C_+_+_1_7_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee ssttrruuccttuurreedd bbiinnddiinngg iinn CC++++1177 ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::551144 ****** | │ │ │ │ │ +|auto const first_leaf = merkle_first_leaf(num_leafs); | │ │ │ │ │ +| auto const block_tree_index = first_leaf + block_index; | │ │ │ │ │ +| | │ │ │ │ │ +| if (blocks_verified(block_index, 1)) | │ │ │ │ │ +| { | │ │ │ │ │ +| // if this blocks's hash is already known, check the passed-in hash against it | │ │ │ │ │ +| if (compare_node(block_tree_index, h)) | │ │ │ │ │ +| return std::make_tuple(set_block_result::ok, block_index, 1); | │ │ │ │ │ +| else | │ │ │ │ │ +| return std::make_tuple(set_block_result::block_hash_failed, block_index, 1); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| for (auto const& n : m_dht_router_nodes) | │ │ │ │ │ +| allocate_full(); | │ │ │ │ │ +| | │ │ │ │ │ +| m_tree[block_tree_index] = h; | │ │ │ │ │ +| | │ │ │ │ │ +| // to avoid wasting a lot of time hashing nodes only to discover they | │ │ │ │ │ +| // cannot be verified, check first to see if the root of the largest | │ │ │ │ │ +| // computable subtree is known | │ │ │ │ │ +| | │ │ │ │ │ +|int leafs_start; | │ │ │ │ │ +|int leafs_size; | │ │ │ │ │ +| int root_index; | │ │ │ │ │ +| std::tie(leafs_start, leafs_size, root_index) = | │ │ │ │ │ +| merkle_find_known_subtree(m_tree, block_index, m_num_blocks); | │ │ │ │ │ +| | │ │ │ │ │ +| // if the root node is unknown the hashes cannot be verified yet | │ │ │ │ │ +| if (m_tree[root_index].is_all_zeros()) | │ │ │ │ │ +| return std::make_tuple(set_block_result::unknown, leafs_start, leafs_size); | │ │ │ │ │ +| | │ │ │ │ │ +| // save the root hash because merkle_fill_tree will overwrite it | │ │ │ │ │ +| sha256_hash const root = m_tree[root_index]; | │ │ │ │ │ +| merkle_fill_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ +| | │ │ │ │ │ +| if (root != m_tree[root_index]) | │ │ │ │ │ | { | │ │ │ │ │ -| m_dht->add_router_node(n); | │ │ │ │ │ +| // hash failure, clear all the internal nodes | │ │ │ │ │ +| // the whole piece failed the hash check. Clear all block hashes | │ │ │ │ │ +| // in this piece and report a hash failure | │ │ │ │ │ +| merkle_clear_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ +| m_tree[root_index] = root; | │ │ │ │ │ +| return std::make_tuple(set_block_result::hash_failed, leafs_start, leafs_size); | │ │ │ │ │ +|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_5_3_9_ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _d_o_n_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_l_y_ _i_f_ _b_i_t_f_i_e_l_d_ _h_a_d_ _a_ _f_u_n_c_t_i_o_n_ _t_o_ _s_e_t_ _a_ _r_a_n_g_e_ _o_f_ _b_i_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ccoouulldd bbee ddoonnee mmoorree eeffffiicciieennttllyy iiff bbiittffiieelldd hhaadd aa ffuunnccttiioonn ttoo sseett aa rraannggee ooff bbiittss ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::553399 ****** | │ │ │ │ │ +|merkle_find_known_subtree(m_tree, block_index, m_num_blocks); | │ │ │ │ │ +| | │ │ │ │ │ +| // if the root node is unknown the hashes cannot be verified yet | │ │ │ │ │ +| if (m_tree[root_index].is_all_zeros()) | │ │ │ │ │ +| return std::make_tuple(set_block_result::unknown, leafs_start, leafs_size); | │ │ │ │ │ +| | │ │ │ │ │ +| // save the root hash because merkle_fill_tree will overwrite it | │ │ │ │ │ +| sha256_hash const root = m_tree[root_index]; | │ │ │ │ │ +| merkle_fill_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ +| | │ │ │ │ │ +| if (root != m_tree[root_index]) | │ │ │ │ │ +| { | │ │ │ │ │ +| // hash failure, clear all the internal nodes | │ │ │ │ │ +| // the whole piece failed the hash check. Clear all block hashes | │ │ │ │ │ +| // in this piece and report a hash failure | │ │ │ │ │ +| merkle_clear_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ +| m_tree[root_index] = root; | │ │ │ │ │ +| return std::make_tuple(set_block_result::hash_failed, leafs_start, leafs_size); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| for (auto const& n : m_dht_nodes) | │ │ │ │ │ -|_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_6_2_6_7_ _ _|_a_s_s_e_r_t_s_ _t_h_a_t_ _n_o_ _o_u_t_s_t_a_n_d_i_n_g_ _a_s_y_n_c_ _o_p_e_r_a_t_i_o_n_s_ _a_r_e_ _s_t_i_l_l_ _i_n_ _f_l_i_g_h_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aasssseerrttss tthhaatt nnoo oouuttssttaannddiinngg aassyynncc ooppeerraattiioonnss aarree ssttiillll iinn fflliigghhtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::66226677 ****** | │ │ │ │ │ -|if (!m_dht) return; | │ │ │ │ │ -| m_dht->direct_request(ep, e, std::bind(&on_direct_response, std::ref(m_alerts), userdata, _1)); | │ │ │ │ │ +|int const leafs_end = std::min(m_num_blocks, leafs_start + leafs_size); | │ │ │ │ │ +|for (int i = leafs_start; i < leafs_end; ++i) | │ │ │ │ │ +| m_block_verified.set_bit(i); | │ │ │ │ │ +| | │ │ │ │ │ +| // attempting to optimize storage is quite costly, only do it if we have | │ │ │ │ │ +| // a reason to believe it might have an effect | │ │ │ │ │ +| if (block_index == m_num_blocks - 1 || !m_tree[block_tree_index + 1].is_all_zeros()) | │ │ │ │ │ +| optimize_storage(); | │ │ │ │ │ +| | │ │ │ │ │ +| return std::make_tuple(set_block_result::ok, leafs_start, leafs_size); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#endif | │ │ │ │ │ +| std::size_t merkle_tree::size() const | │ │ │ │ │ +| { | │ │ │ │ │ +| return static_cast(merkle_num_nodes(merkle_num_leafs(m_num_blocks))); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| bool session_impl::is_listening() const | │ │ │ │ │ +| int merkle_tree::num_pieces() const | │ │ │ │ │ | { | │ │ │ │ │ -| return !m_listen_sockets.empty(); | │ │ │ │ │ +| int const ps = blocks_per_piece(); | │ │ │ │ │ +| TORRENT_ASSERT(ps > 0); | │ │ │ │ │ +| return (m_num_blocks + ps - 1) >> m_blocks_per_piece_log; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| session_impl::~session_impl() | │ │ │ │ │ +| int merkle_tree::block_layer_start() const | │ │ │ │ │ | { | │ │ │ │ │ -| // since we're destructing the session, no more alerts will make it out to | │ │ │ │ │ -| // the user. So stop posting them now | │ │ │ │ │ -| m_alerts.set_alert_mask({}); | │ │ │ │ │ -| m_alerts.set_notify_function({}); | │ │ │ │ │ +| int const num_leafs = merkle_num_leafs(m_num_blocks); | │ │ │ │ │ +| TORRENT_ASSERT(num_leafs > 0); | │ │ │ │ │ +| return merkle_first_leaf(num_leafs); | │ │ │ │ │ +|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_._c_p_p_:|pre C++17, GCC and msvc does not make std::string nothrow move assignable, which means no type containing a string will be nothrow | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_7_8_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _a_s_s_i_g_n_a_b_l_e_ _b_y_ _d_e_f_a_u_l_t_ _e_i_t_h_e_r_ _s_t_a_t_i_c___a_s_s_e_r_t_(_s_t_d_:_:_i_s___n_o_t_h_r_o_w___m_o_v_e___a_s_s_i_g_n_a_b_l_e_:_:_v_a_l_u_e_ _,_ _"_s_h_o_u_l_d_ _b_e_ _n_o_t_h_r_o_w_ _m_o_v_e_ _a_s_s_i_g_n_a_b_l_e_"_)_;_ _ _ _ _ _ | │ │ │ │ │ +|********** pprree CC++++1177,, GGCCCC aanndd mmssvvcc ddooeess nnoott mmaakkee ssttdd::::ssttrriinngg nnootthhrrooww mmoovvee aassssiiggnnaabbllee,, wwhhiicchh mmeeaannss nnoo ttyyppee ccoonnttaaiinniinngg aa ssttrriinngg wwiillll bbee nnootthhrrooww mmoovvee aassssiiggnnaabbllee bbyy ddeeffaauulltt eeiitthheerr | │ │ │ │ │ +|ssttaattiicc__aasssseerrtt((ssttdd::::iiss__nnootthhrrooww__mmoovvee__aassssiiggnnaabbllee::::vvaalluuee ,, ""sshhoouulldd bbee nnootthhrrooww mmoovvee aassssiiggnnaabbllee""));; ********** | │ │ │ │ │ +|****** ....//ssrrcc//aadddd__ttoorrrreenntt__ppaarraammss..ccpppp::7788 ****** | │ │ │ │ │ +|DECL_FLAG(sequential_download); | │ │ │ │ │ +| DECL_FLAG(pinned); | │ │ │ │ │ +| DECL_FLAG(stop_when_ready); | │ │ │ │ │ +| DECL_FLAG(override_trackers); | │ │ │ │ │ +| DECL_FLAG(override_web_seeds); | │ │ │ │ │ +| DECL_FLAG(need_save_resume); | │ │ │ │ │ +| DECL_FLAG(override_resume_data); | │ │ │ │ │ +| DECL_FLAG(merge_resume_trackers); | │ │ │ │ │ +| DECL_FLAG(use_resume_save_path); | │ │ │ │ │ +| DECL_FLAG(merge_resume_http_seeds); | │ │ │ │ │ +| DECL_FLAG(default_flags); | │ │ │ │ │ +|#undef DECL_FLAG | │ │ │ │ │ +|#endif // TORRENT_ABI_VERSION | │ │ │ │ │ | | │ │ │ │ │ -| // this is not allowed to be the network thread! | │ │ │ │ │ -|// TORRENT_ASSERT(is_not_thread()); | │ │ │ │ │ +| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ +| , "should be nothrow move constructible"); | │ │ │ │ │ | | │ │ │ │ │ -|// this can happen if we end the io_context run loop with an exception | │ │ │ │ │ -| m_connections.clear(); | │ │ │ │ │ -| for (auto& t : m_torrents) | │ │ │ │ │ -| { | │ │ │ │ │ -| t->panic(); | │ │ │ │ │ -| t->abort(); | │ │ │ │ │ -| } | │ │ │ │ │ -| m_torrents.clear(); | │ │ │ │ │ +| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ +| , "should be nothrow move constructible"); | │ │ │ │ │ | | │ │ │ │ │ -| // this has probably been called already, but in case of sudden | │ │ │ │ │ -| // termination through an exception, it may not have been done | │ │ │ │ │ -| abort_stage2(); | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_._c_p_p_:|it would be nice if this was nothrow default constructible static_assert(std::is_nothrow_default_constructible::value , "should be | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_8_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_n_o_t_h_r_o_w_ _d_e_f_a_u_l_t_ _c_o_n_s_t_r_u_c_t_i_b_l_e_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee iiff tthhiiss wwaass nnootthhrrooww ddeeffaauulltt ccoonnssttrruuccttiibbllee ssttaattiicc__aasssseerrtt((ssttdd::::iiss__nnootthhrrooww__ddeeffaauulltt__ccoonnssttrruuccttiibbllee::::vvaalluuee ,, ""sshhoouulldd bbee nnootthhrrooww ddeeffaauulltt ccoonnssttrruuccttiibbllee""));; **********| │ │ │ │ │ +|****** ....//ssrrcc//aadddd__ttoorrrreenntt__ppaarraammss..ccpppp::8844 ****** | │ │ │ │ │ +|DECL_FLAG(pinned); | │ │ │ │ │ +| DECL_FLAG(stop_when_ready); | │ │ │ │ │ +| DECL_FLAG(override_trackers); | │ │ │ │ │ +| DECL_FLAG(override_web_seeds); | │ │ │ │ │ +| DECL_FLAG(need_save_resume); | │ │ │ │ │ +| DECL_FLAG(override_resume_data); | │ │ │ │ │ +| DECL_FLAG(merge_resume_trackers); | │ │ │ │ │ +| DECL_FLAG(use_resume_save_path); | │ │ │ │ │ +| DECL_FLAG(merge_resume_http_seeds); | │ │ │ │ │ +| DECL_FLAG(default_flags); | │ │ │ │ │ +|#undef DECL_FLAG | │ │ │ │ │ +|#endif // TORRENT_ABI_VERSION | │ │ │ │ │ | | │ │ │ │ │ -|#if defined TORRENT_ASIO_DEBUGGING | │ │ │ │ │ -| FILE* f = fopen("wakeups.log", "w+"); | │ │ │ │ │ -| if (f != nullptr) | │ │ │ │ │ -| { | │ │ │ │ │ -| time_point m = min_time(); | │ │ │ │ │ -| if (!_wakeups.empty()) m = _wakeups[0].timestamp; | │ │ │ │ │ -| time_point prev = m; | │ │ │ │ │ -| std::uint64_t prev_csw = 0; | │ │ │ │ │ -| if (!_wakeups.empty()) prev_csw = _wakeups[0].context_switches; | │ │ │ │ │ -| std::fprintf(f, "abs. time\trel. time\tctx switch\tidle-wakeup\toperation\n"); | │ │ │ │ │ -| for (wakeup_t const& w : _wakeups) | │ │ │ │ │ -| { | │ │ │ │ │ -| bool const idle_wakeup = w.context_switches > prev_csw; | │ │ │ │ │ -| std::fprintf(f, "%" PRId64 "\t%" PRId64 "\t%" PRId64 "\t%c\t%s\n" | │ │ │ │ │ -| , total_microseconds(w.timestamp - m) | │ │ │ │ │ -| , total_microseconds(w.timestamp - prev) | │ │ │ │ │ -|_ _ _ _ _ _,_ _w_._c_o_n_t_e_x_t___s_w_i_t_c_h_e_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ +| , "should be nothrow move constructible"); | │ │ │ │ │ +| | │ │ │ │ │ +| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ +| , "should be nothrow move constructible"); | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|namespace aux { | │ │ │ │ │ +| | │ │ │ │ │ +| // returns whether this add_torrent_params object has "resume-data", i.e. | │ │ │ │ │ +| // information about which pieces we have. | │ │ │ │ │ +| bool contains_resume_data(add_torrent_params const& atp) | │ │ │ │ │ +| { | │ │ │ │ │ +| return !atp.have_pieces.empty() | │ │ │ │ │ +| || (atp.flags & torrent_flags::seed_mode); | │ │ │ │ │ +| } | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_s_r_c_/_p_a_r_t___f_i_l_e_._c_p_p_:_3_0_0 |what do we do if someone is currently reading from the disk from this piece? does it matter? Since we won't actively erase the data | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_f_r_o_m_ _d_i_s_k_,_ _b_u_t_ _i_t_ _m_a_y_ _b_e_ _o_v_e_r_w_r_i_t_t_e_n_ _s_o_o_n_,_ _i_t_'_s_ _p_r_o_b_a_b_l_y_ _n_o_t_ _t_h_a_t_ _b_i_g_ _o_f_ _a_ _d_e_a_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** wwhhaatt ddoo wwee ddoo iiff ssoommeeoonnee iiss ccuurrrreennttllyy rreeaaddiinngg ffrroomm tthhee ddiisskk ffrroomm tthhiiss ppiieeccee?? ddooeess iitt mmaatttteerr?? SSiinnccee wwee wwoonn''tt aaccttiivveellyy eerraassee tthhee ddaattaa ffrroomm ddiisskk,, bbuutt iitt mmaayy bbee oovveerrwwrriitttteenn | │ │ │ │ │ |ssoooonn,, iitt''ss pprroobbaabbllyy nnoott tthhaatt bbiigg ooff aa ddeeaall ********** | │ │ │ │ │ |****** ....//ssrrcc//ppaarrtt__ffiillee..ccpppp::330000 ****** | │ │ │ │ │ |create_directories(m_path, ec); | │ │ │ │ │ | if (ec) return {}; | │ │ │ │ │ @@ -7448,122 +8484,175 @@ │ │ │ │ │ | char* ptr = header.data(); | │ │ │ │ │ | write_uint32(m_max_pieces, ptr); | │ │ │ │ │ | write_uint32(m_piece_size, ptr); | │ │ │ │ │ | | │ │ │ │ │ | for (piece_index_t piece(0); piece < piece_index_t(m_max_pieces); ++piece) | │ │ │ │ │ | { | │ │ │ │ │ |_ _ _ _a_u_t_o_ _c_o_n_s_t_ _i_ _=_ _m___p_i_e_c_e___m_a_p_._f_i_n_d_(_p_i_e_c_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_u_t_p___s_t_r_e_a_m_._c_p_p_:_1_4_6_7_ _ _ _ _|_t_h_i_s_ _l_o_o_p_ _i_s_ _n_o_t_ _v_e_r_y_ _e_f_f_i_c_i_e_n_t_._ _I_t_ _c_o_u_l_d_ _b_e_ _f_i_x_e_d_ _b_y_ _h_a_v_i_n_g_ _a_ _s_e_p_a_r_a_t_e_ _l_i_s_t_ _o_f_ _s_e_q_u_e_n_c_e_ _n_u_m_b_e_r_s_ _t_h_a_t_ _n_e_e_d_ _r_e_s_e_n_d_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss lloooopp iiss nnoott vveerryy eeffffiicciieenntt.. IItt ccoouulldd bbee ffiixxeedd bbyy hhaavviinngg aa sseeppaarraattee lliisstt ooff sseeqquueennccee nnuummbbeerrss tthhaatt nneeeedd rreesseennddiinngg ********** | │ │ │ │ │ -|****** ....//ssrrcc//uuttpp__ssttrreeaamm..ccpppp::11446677 ****** | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_stalled) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (flags & pkt_ack) | │ │ │ │ │ -| defer_ack(); | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // m_out_eof means we're trying to close the write side of this socket, | │ │ │ │ │ -| // we need to flush all payload before we can send the FIN packet, so don't | │ │ │ │ │ -| // store any payload in the nagle packet | │ │ │ │ │ -| bool const force = (flags & pkt_ack) || (flags & pkt_fin) || m_out_eof; | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |this should be the global download rate | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_1_1_0_5_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd bbee tthhee gglloobbaall ddoowwnnllooaadd rraattee ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::11110055 ****** | │ │ │ │ │ +| int rate = 0; | │ │ │ │ │ | | │ │ │ │ │ -| // when we want to close the outgoing stream, we need to send the | │ │ │ │ │ -| // remaining nagle packet even though it won't fill a packet. | │ │ │ │ │ -| bool const force_flush_nagle = m_out_eof && m_write_buffer_size; | │ │ │ │ │ +| // if we haven't received any data recently, the current download rate | │ │ │ │ │ +| // is not representative | │ │ │ │ │ +| if (aux::time_now() - m_last_piece.get(m_connect) > seconds(30) && m_download_rate_peak > 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| rate = m_download_rate_peak; | │ │ │ │ │ +| } | │ │ │ │ │ +| else if (aux::time_now() - m_last_unchoked.get(m_connect) < seconds(5) | │ │ │ │ │ +| && m_statistics.total_payload_upload() < 2 * 0x4000) | │ │ │ │ │ +| { | │ │ │ │ │ +| // if we're have only been unchoked for a short period of time, | │ │ │ │ │ +| // we don't know what rate we can get from this peer. Instead of assuming | │ │ │ │ │ +| // the lowest possible rate, assume the average. | │ │ │ │ │ | | │ │ │ │ │ -| // first see if we need to resend any packets | │ │ │ │ │ +| int peers_with_requests = int(stats_counters()[counters::num_peers_down_requests]); | │ │ │ │ │ +| // avoid division by 0 | │ │ │ │ │ +| if (peers_with_requests == 0) peers_with_requests = 1; | │ │ │ │ │ | | │ │ │ │ │ -|for (int i = (m_acked_seq_nr + 1) & ACK_MASK; i != m_seq_nr; i = (i + 1) & ACK_MASK) | │ │ │ │ │ -|{ | │ │ │ │ │ -| packet* p = m_outbuf.at(aux::numeric_cast(i)); | │ │ │ │ │ -| if (!p) continue; | │ │ │ │ │ -| if (!p->need_resend) continue; | │ │ │ │ │ -| if (!resend_packet(p)) | │ │ │ │ │ +|rate = t->statistics().transfer_rate(stat::download_payload) / peers_with_requests; | │ │ │ │ │ +|} | │ │ │ │ │ +| else | │ │ │ │ │ | { | │ │ │ │ │ -| // we couldn't resend the packet. It probably doesn't | │ │ │ │ │ -| // fit in our cwnd. If force is set, we need to continue | │ │ │ │ │ -| // to send our packet anyway, if we don't have force set, | │ │ │ │ │ -| // we might as well return | │ │ │ │ │ -| if (!force) return false; | │ │ │ │ │ -| // resend_packet might have failed | │ │ │ │ │ -| if (state() == state_t::error_wait || state() == state_t::deleting) return false; | │ │ │ │ │ -| if (m_stalled) return false; | │ │ │ │ │ -| break; | │ │ │ │ │ +| // current download rate in bytes per seconds | │ │ │ │ │ +| rate = m_statistics.transfer_rate(stat::download_payload); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // don't fast-resend this packet | │ │ │ │ │ -| if (m_fast_resend_seq_nr == i) | │ │ │ │ │ -| m_fast_resend_seq_nr = (m_fast_resend_seq_nr + 1) & ACK_MASK; | │ │ │ │ │ -| } | │ │ │ │ │ +| // avoid division by zero | │ │ │ │ │ +| if (rate < 50) rate = 50; | │ │ │ │ │ | | │ │ │ │ │ -| // MTU DISCOVERY | │ │ │ │ │ +| // average of current rate and peak | │ │ │ │ │ +|// rate = (rate + m_download_rate_peak) / 2; | │ │ │ │ │ | | │ │ │ │ │ -| // under these conditions, the next packet we send should be an MTU probe. | │ │ │ │ │ -| // MTU probes get to use the mid-point packet size, whereas other packets | │ │ │ │ │ -| // use a conservative packet size of the largest known to work. The reason | │ │ │ │ │ -| // for the cwnd condition is to make sure the probe is surrounded by non- | │ │ │ │ │ -| // probes, to be able to distinguish a loss of the probe vs. just loss in | │ │ │ │ │ -|_ _/_/_ _g_e_n_e_r_a_l_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t___h_a_n_d_l_e_._c_p_p_:_5_8_9_ _|_s_u_p_p_o_r_t_ _m_o_v_i_n_g_ _f_i_l_e_s_ _i_n_t_o_ _t_h_i_s_ _c_a_l_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssuuppppoorrtt mmoovviinngg ffiilleess iinnttoo tthhiiss ccaallll ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt__hhaannddllee..ccpppp::558899 ****** | │ │ │ │ │ -|auto retp = &prio; | │ │ │ │ │ -| sync_call(&torrent::piece_priorities, retp); | │ │ │ │ │ -| std::vector ret; | │ │ │ │ │ -| ret.reserve(prio.size()); | │ │ │ │ │ -| for (auto p : prio) | │ │ │ │ │ -| ret.push_back(int(static_cast(p))); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| return milliseconds((m_outstanding_bytes + extra_bytes | │ │ │ │ │ +| + m_queued_time_critical * t->block_size() * 1000) / rate); | │ │ │ │ │ | } | │ │ │ │ │ -|#endif | │ │ │ │ │ | | │ │ │ │ │ -| void torrent_handle::file_priority(file_index_t index, download_priority_t priority) const | │ │ │ │ │ +| void peer_connection::add_stat(std::int64_t const downloaded, std::int64_t const uploaded) | │ │ │ │ │ | { | │ │ │ │ │ -| async_call(&torrent::set_file_priority, index, priority); | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| m_statistics.add_stat(downloaded, uploaded); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| download_priority_t torrent_handle::file_priority(file_index_t index) const | │ │ │ │ │ +| sha1_hash peer_connection::associated_info_hash() const | │ │ │ │ │ | { | │ │ │ │ │ -| return sync_call_ret(dont_download, &torrent::file_priority, index); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|void torrent_handle::prioritize_files(std::vector const& files) const | │ │ │ │ │ -|{ | │ │ │ │ │ -| async_call(&torrent::prioritize_files | │ │ │ │ │ -| , static_cast const&>(files)); | │ │ │ │ │ +| std::shared_ptr t = associated_torrent().lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ +| auto const& ih = t->info_hash(); | │ │ │ │ │ +| // if protocol_v2 is set on the peer, this better be a v2 torrent, | │ │ │ │ │ +|_ _ _/_/_ _o_t_h_e_r_w_i_s_e_ _s_o_m_e_t_h_i_n_g_ _i_s_n_'_t_ _r_i_g_h_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |sort the allowed fast set in priority order | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_3_5_3_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssoorrtt tthhee aalllloowweedd ffaasstt sseett iinn pprriioorriittyy oorrddeerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::33553366 ****** | │ │ │ │ │ +| // if the peer has the piece and we want | │ │ │ │ │ +| // to download it, request it | │ │ │ │ │ +| if (index < m_have_piece.end_index() | │ │ │ │ │ +| && m_have_piece[index] | │ │ │ │ │ +| && !t->have_piece(index) | │ │ │ │ │ +| && t->valid_metadata() | │ │ │ │ │ +| && t->has_picker() | │ │ │ │ │ +| && t->picker().piece_priority(index) > dont_download) | │ │ │ │ │ +| { | │ │ │ │ │ +| t->peer_is_interesting(*this); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::vector torrent_handle::get_file_priorities() const | │ │ │ │ │ +| std::vector const& peer_connection::allowed_fast() | │ │ │ │ │ | { | │ │ │ │ │ -| aux::vector ret; | │ │ │ │ │ -| auto retp = &ret; | │ │ │ │ │ -| sync_call(&torrent::file_priorities, retp); | │ │ │ │ │ -| return TORRENT_RVO(ret); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ | | │ │ │ │ │ -|// ============ start deprecation =============== | │ │ │ │ │ +|return m_allowed_fast; | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| void torrent_handle::prioritize_files(std::vector const& files) const | │ │ │ │ │ +| bool peer_connection::can_request_time_critical() const | │ │ │ │ │ | { | │ │ │ │ │ -| aux::vector file_prio; | │ │ │ │ │ -| file_prio.reserve(files.size()); | │ │ │ │ │ -| for (auto const p : files) { | │ │ │ │ │ -| file_prio.push_back(download_priority_t(static_cast(p))); | │ │ │ │ │ -| } | │ │ │ │ │ -| async_call(&torrent::prioritize_files, file_prio); | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| if (has_peer_choked() || !is_interesting()) return false; | │ │ │ │ │ +| if (int(m_download_queue.size()) + int(m_request_queue.size()) | │ │ │ │ │ +| > m_desired_queue_size * 2) return false; | │ │ │ │ │ +| if (on_parole()) return false; | │ │ │ │ │ +| if (m_disconnecting) return false; | │ │ │ │ │ +| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ +| if (t->upload_mode()) return false; | │ │ │ │ │ +| | │ │ │ │ │ +| // ignore snubbed peers, since they're not likely to return pieces in a | │ │ │ │ │ +| // timely manner anyway | │ │ │ │ │ +| if (m_snubbed) return false; | │ │ │ │ │ +| return true; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::vector torrent_handle::file_priorities() const | │ │ │ │ │ +| bool peer_connection::make_time_critical(piece_block const& block) | │ │ │ │ │ | { | │ │ │ │ │ -|_ _ _a_u_x_:_:_v_e_c_t_o_r_<_d_o_w_n_l_o_a_d___p_r_i_o_r_i_t_y___t_,_ _f_i_l_e___i_n_d_e_x___t_>_ _p_r_i_o_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ +| auto const rit = std::find_if(m_request_queue.begin() | │ │ │ │ │ +| , m_request_queue.end(), aux::has_block(block)); | │ │ │ │ │ +| if (rit == m_request_queue.end()) return false; | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ +| TORRENT_ASSERT(t); | │ │ │ │ │ +|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T_(_t_-_>_h_a_s___p_i_c_k_e_r_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_i_p___n_o_t_i_f_i_e_r_._c_p_p_:_4_1_ _ _ _ _ _|_s_i_m_u_l_a_t_o_r_ _s_u_p_p_o_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssiimmuullaattoorr ssuuppppoorrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//iipp__nnoottiiffiieerr..ccpppp::4411 ****** | │ │ │ │ │ +| from this software without specific prior written permission. | │ │ │ │ │ +| | │ │ │ │ │ +|THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | │ │ │ │ │ +|AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | │ │ │ │ │ +|IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | │ │ │ │ │ +|ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | │ │ │ │ │ +|LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | │ │ │ │ │ +|CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | │ │ │ │ │ +|SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | │ │ │ │ │ +|INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | │ │ │ │ │ +|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ +|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ +|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ +| | │ │ │ │ │ +|*/ | │ │ │ │ │ +| | │ │ │ │ │ +|#include "libtorrent/aux_/ip_notifier.hpp" | │ │ │ │ │ +|#include "libtorrent/assert.hpp" | │ │ │ │ │ +| | │ │ │ │ │ +|#if defined TORRENT_BUILD_SIMULATOR | │ │ │ │ │ +|#elif TORRENT_USE_NETLINK | │ │ │ │ │ +|#include "libtorrent/netlink.hpp" | │ │ │ │ │ +|#include "libtorrent/socket.hpp" | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ +|#elif TORRENT_USE_SYSTEMCONFIGURATION || TORRENT_USE_SC_NETWORK_REACHABILITY | │ │ │ │ │ +|#include | │ │ │ │ │ +|#elif defined TORRENT_WINDOWS | │ │ │ │ │ +|#include "libtorrent/aux_/throw.hpp" | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ +|#include | │ │ │ │ │ +|#ifdef TORRENT_WINRT | │ │ │ │ │ +|#include | │ │ │ │ │ +|#endif | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|#include "libtorrent/aux_/netlink_utils.hpp" | │ │ │ │ │ +| | │ │ │ │ │ +|namespace libtorrent { namespace aux { | │ │ │ │ │ +| | │ │ │ │ │ +|namespace { | │ │ │ │ │ +| | │ │ │ │ │ +|#if (TORRENT_USE_SYSTEMCONFIGURATION || TORRENT_USE_SC_NETWORK_REACHABILITY) && \ | │ │ │ │ │ +| !defined TORRENT_BUILD_SIMULATOR | │ │ │ │ │ +| | │ │ │ │ │ +|// common utilities for Mac and iOS | │ │ │ │ │ +|template void CFRefRetain(T h) { CFRetain(h); } | │ │ │ │ │ +|_t_e_m_p_l_a_t_e_ _<_t_y_p_e_n_a_m_e_ _T_>_ _v_o_i_d_ _C_F_R_e_f_R_e_l_e_a_s_e_(_T_ _h_)_ _{_ _C_F_R_e_l_e_a_s_e_(_h_)_;_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_t_t_i_n_g_s___p_a_c_k_._c_p_p_:_3_0_5_ _ _|_d_e_p_r_e_c_a_t_e_ _t_h_i_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ddeepprreeccaattee tthhiiss ********** | │ │ │ │ │ |****** ....//ssrrcc//sseettttiinnggss__ppaacckk..ccpppp::330055 ****** | │ │ │ │ │ |SET(outgoing_port, 0, nullptr), | │ │ │ │ │ | SET(num_outgoing_ports, 0, nullptr), | │ │ │ │ │ | SET(peer_dscp, 0x04, &session_impl::update_peer_dscp), | │ │ │ │ │ | SET(active_downloads, 3, &session_impl::trigger_auto_manage), | │ │ │ │ │ @@ -7664,122 +8753,185 @@ │ │ │ │ │ | sett.bulk_set([&](aux::session_settings_single_thread& s) | │ │ │ │ │ | { | │ │ │ │ │ | apply_pack_impl(pack, s, ses ? &callbacks : nullptr); | │ │ │ │ │ | }); | │ │ │ │ │ | | │ │ │ │ │ | // call the callbacks once all the settings have been applied, and | │ │ │ │ │ |_ _ _/_/_ _o_n_l_y_ _o_n_c_e_ _p_e_r_ _c_a_l_l_b_a_c_k_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/ |why is this a linked list? | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_u_d_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_6_3_3_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** wwhhyy iiss tthhiiss aa lliinnkkeedd lliisstt?? ********** | │ │ │ │ │ -|****** ....//ssrrcc//uuddpp__ttrraacckkeerr__ccoonnnneeccttiioonn..ccpppp::663333 ****** | │ │ │ │ │ -|ipv6_peer_entry e{}; | │ │ │ │ │ -| std::memcpy(e.ip.data(), buf.data(), 16); | │ │ │ │ │ -| buf = buf.subspan(16); | │ │ │ │ │ -| e.port = aux::read_uint16(buf); | │ │ │ │ │ -| resp.peers6.push_back(e); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| resp.peers4.reserve(static_cast(num_peers)); | │ │ │ │ │ -| for (int i = 0; i < num_peers; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| ipv4_peer_entry e{}; | │ │ │ │ │ -| std::memcpy(e.ip.data(), buf.data(), 4); | │ │ │ │ │ -| buf = buf.subspan(4); | │ │ │ │ │ -| e.port = aux::read_uint16(buf); | │ │ │ │ │ -| resp.peers4.push_back(e); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_u_t_p___s_t_r_e_a_m_._c_p_p_:_1_4_6_7_ _ _ _ _|_t_h_i_s_ _l_o_o_p_ _i_s_ _n_o_t_ _v_e_r_y_ _e_f_f_i_c_i_e_n_t_._ _I_t_ _c_o_u_l_d_ _b_e_ _f_i_x_e_d_ _b_y_ _h_a_v_i_n_g_ _a_ _s_e_p_a_r_a_t_e_ _l_i_s_t_ _o_f_ _s_e_q_u_e_n_c_e_ _n_u_m_b_e_r_s_ _t_h_a_t_ _n_e_e_d_ _r_e_s_e_n_d_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss lloooopp iiss nnoott vveerryy eeffffiicciieenntt.. IItt ccoouulldd bbee ffiixxeedd bbyy hhaavviinngg aa sseeppaarraattee lliisstt ooff sseeqquueennccee nnuummbbeerrss tthhaatt nneeeedd rreesseennddiinngg ********** | │ │ │ │ │ +|****** ....//ssrrcc//uuttpp__ssttrreeaamm..ccpppp::11446677 ****** | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -|std::list
    ip_list; | │ │ │ │ │ -|std::transform(m_endpoints.begin(), m_endpoints.end(), std::back_inserter(ip_list) | │ │ │ │ │ -| , [](tcp::endpoint const& ep) { return ep.address(); } ); | │ │ │ │ │ +| if (m_stalled) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (flags & pkt_ack) | │ │ │ │ │ +| defer_ack(); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| cb->tracker_response(tracker_req(), m_target.address(), ip_list, resp); | │ │ │ │ │ +| // m_out_eof means we're trying to close the write side of this socket, | │ │ │ │ │ +| // we need to flush all payload before we can send the FIN packet, so don't | │ │ │ │ │ +| // store any payload in the nagle packet | │ │ │ │ │ +| bool const force = (flags & pkt_ack) || (flags & pkt_fin) || m_out_eof; | │ │ │ │ │ | | │ │ │ │ │ -| close(); | │ │ │ │ │ -| return true; | │ │ │ │ │ -| } | │ │ │ │ │ +| // when we want to close the outgoing stream, we need to send the | │ │ │ │ │ +| // remaining nagle packet even though it won't fill a packet. | │ │ │ │ │ +| bool const force_flush_nagle = m_out_eof && m_write_buffer_size; | │ │ │ │ │ | | │ │ │ │ │ -| bool udp_tracker_connection::on_scrape_response(span buf) | │ │ │ │ │ -| { | │ │ │ │ │ -| restart_read_timeout(); | │ │ │ │ │ -| auto const action = static_cast(aux::read_int32(buf)); | │ │ │ │ │ -| std::uint32_t const transaction = aux::read_uint32(buf); | │ │ │ │ │ +| // first see if we need to resend any packets | │ │ │ │ │ | | │ │ │ │ │ -| if (transaction != m_transaction_id) | │ │ │ │ │ +|for (int i = (m_acked_seq_nr + 1) & ACK_MASK; i != m_seq_nr; i = (i + 1) & ACK_MASK) | │ │ │ │ │ +|{ | │ │ │ │ │ +| packet* p = m_outbuf.at(aux::numeric_cast(i)); | │ │ │ │ │ +| if (!p) continue; | │ │ │ │ │ +| if (!p->need_resend) continue; | │ │ │ │ │ +| if (!resend_packet(p)) | │ │ │ │ │ | { | │ │ │ │ │ -| fail(error_code(errors::invalid_tracker_transaction_id), operation_t::bittorrent); | │ │ │ │ │ -| return false; | │ │ │ │ │ +| // we couldn't resend the packet. It probably doesn't | │ │ │ │ │ +| // fit in our cwnd. If force is set, we need to continue | │ │ │ │ │ +| // to send our packet anyway, if we don't have force set, | │ │ │ │ │ +| // we might as well return | │ │ │ │ │ +| if (!force) return false; | │ │ │ │ │ +| // resend_packet might have failed | │ │ │ │ │ +| if (state() == state_t::error_wait || state() == state_t::deleting) return false; | │ │ │ │ │ +| if (m_stalled) return false; | │ │ │ │ │ +| break; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (action == action_t::error) | │ │ │ │ │ +| // don't fast-resend this packet | │ │ │ │ │ +| if (m_fast_resend_seq_nr == i) | │ │ │ │ │ +| m_fast_resend_seq_nr = (m_fast_resend_seq_nr + 1) & ACK_MASK; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // MTU DISCOVERY | │ │ │ │ │ +| | │ │ │ │ │ +| // under these conditions, the next packet we send should be an MTU probe. | │ │ │ │ │ +| // MTU probes get to use the mid-point packet size, whereas other packets | │ │ │ │ │ +| // use a conservative packet size of the largest known to work. The reason | │ │ │ │ │ +| // for the cwnd condition is to make sure the probe is surrounded by non- | │ │ │ │ │ +| // probes, to be able to distinguish a loss of the probe vs. just loss in | │ │ │ │ │ +|_ _/_/_ _g_e_n_e_r_a_l_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_u_t_p___s_o_c_k_e_t___m_a_n_a_g_e_r_._c_p_p_:|this should not be heap allocated, sockets should be movable | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_2_0_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd nnoott bbee hheeaapp aallllooccaatteedd,, ssoocckkeettss sshhoouulldd bbee mmoovvaabbllee ********** | │ │ │ │ │ +|****** ....//ssrrcc//uuttpp__ssoocckkeett__mmaannaaggeerr..ccpppp::220044 ****** | │ │ │ │ │ +|// UTP_LOGV("incoming packet id:%d source:%s\n", id, print_endpoint(ep).c_str()); | │ │ │ │ │ +| | │ │ │ │ │ +| if (!m_sett.get_bool(settings_pack::enable_incoming_utp)) | │ │ │ │ │ +| return false; | │ │ │ │ │ +| | │ │ │ │ │ +| // if not found, see if it's a SYN packet, if it is, | │ │ │ │ │ +| // create a new utp_stream | │ │ │ │ │ +| if (ph->get_type() == ST_SYN) | │ │ │ │ │ | { | │ │ │ │ │ -| fail(error_code(errors::tracker_failure), operation_t::bittorrent | │ │ │ │ │ -| , std::string(buf.data(), static_cast(buf.size())).c_str()); | │ │ │ │ │ +| // possible SYN flood. Just ignore | │ │ │ │ │ +| if (int(m_utp_sockets.size()) > m_sett.get_int(settings_pack::connections_limit) * 2) | │ │ │ │ │ +| return false; | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(m_new_connection == -1); | │ │ │ │ │ +| // create the new socket with this ID | │ │ │ │ │ +| m_new_connection = id; | │ │ │ │ │ +| | │ │ │ │ │ +|// UTP_LOGV("not found, new connection id:%d\n", m_new_connection); | │ │ │ │ │ +| | │ │ │ │ │ +|aux::socket_type c(aux::instantiate_connection(m_ios, aux::proxy_settings(), m_ssl_context, this, true, false)); | │ │ │ │ │ +| | │ │ │ │ │ +| utp_stream* str = nullptr; | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| if (is_ssl(c)) | │ │ │ │ │ +| str = &boost::get>(c).next_layer(); | │ │ │ │ │ +| else | │ │ │ │ │ +|#endif | │ │ │ │ │ +| str = boost::get(&c); | │ │ │ │ │ +| | │ │ │ │ │ +| TORRENT_ASSERT(str); | │ │ │ │ │ +| int const mtu = mtu_for_dest(ep.address()); | │ │ │ │ │ +| str->get_impl()->init_mtu(mtu); | │ │ │ │ │ +| str->get_impl()->m_sock = std::move(socket); | │ │ │ │ │ +| bool const ret = str->get_impl()->incoming_packet(p, ep, receive_time); | │ │ │ │ │ +| if (!ret) return false; | │ │ │ │ │ +| m_last_socket = str->get_impl(); | │ │ │ │ │ +| m_cb(std::move(c)); | │ │ │ │ │ +| // the connection most likely changed its connection ID here | │ │ │ │ │ +| // we need to move it to the correct ID | │ │ │ │ │ | return true; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (action != action_t::scrape) | │ │ │ │ │ -|_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_a_g_n_e_t___u_r_i_._c_p_p_:_4_3_9_ _ _ _ _ _|_w_h_a_t_'_s_ _t_h_e_ _r_i_g_h_t_ _n_u_m_b_e_r_ _h_e_r_e_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** wwhhaatt''ss tthhee rriigghhtt nnuummbbeerr hheerree?? ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmaaggnneett__uurrii..ccpppp::443399 ****** | │ │ │ │ │ -|} | │ │ │ │ │ -| else if (string_equal_no_case(name, "so"_sv)) // select-only (files) | │ │ │ │ │ -| { | │ │ │ │ │ -| // accept only digits, '-' and ',' | │ │ │ │ │ -| if (std::any_of(value.begin(), value.end(), [](char c) | │ │ │ │ │ -| { return !is_digit(c) && c != '-' && c != ','; })) | │ │ │ │ │ -| continue; | │ │ │ │ │ +| if (ph->get_type() == ST_RESET) return false; | │ │ │ │ │ | | │ │ │ │ │ -| // make sure all file priorities are set to 0, except the ones | │ │ │ │ │ -| // we specify in the file_priorities | │ │ │ │ │ -| p.flags |= torrent_flags::default_dont_download; | │ │ │ │ │ +| // #error send reset | │ │ │ │ │ | | │ │ │ │ │ -| do | │ │ │ │ │ -| { | │ │ │ │ │ -| string_view token; | │ │ │ │ │ -| std::tie(token, value) = split_string(value, ','); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (token.empty()) continue; | │ │ │ │ │ +|_ _v_o_i_d_ _u_t_p___s_o_c_k_e_t___m_a_n_a_g_e_r_:_:_s_u_b_s_c_r_i_b_e___w_r_i_t_a_b_l_e_(_u_t_p___s_o_c_k_e_t___i_m_p_l_*_ _s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/ |move stats_counter_t out of counters | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._c_p_p_:_4_0_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee ssttaattss__ccoouunntteerr__tt oouutt ooff ccoouunntteerrss ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_ss_rr_cc_//_pp_ee_rr_ff_oo_rr_mm_aa_nn_cc_ee____cc_oo_uu_nn_tt_ee_rr_ss_.._cc_pp_pp_::_44_00_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/ |should bittorrent keep-alive messages have a counter too? | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._c_p_p_:_4_1_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** sshhoouulldd bbiittttoorrrreenntt kkeeeepp--aalliivvee mmeessssaaggeess hhaavvee aa ccoouunntteerr ttoooo?? ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_ss_rr_cc_//_pp_ee_rr_ff_oo_rr_mm_aa_nn_cc_ee____cc_oo_uu_nn_tt_ee_rr_ss_.._cc_pp_pp_::_44_11_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/ |It would be nice if this could be an internal type. default_disk_constructor depends on it now | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._c_p_p_:_4_2_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** IItt wwoouulldd bbee nniiccee iiff tthhiiss ccoouulldd bbee aann iinntteerrnnaall ttyyppee.. ddeeffaauulltt__ddiisskk__ccoonnssttrruuccttoorr ddeeppeennddss oonn iitt nnooww ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppeerrffoorrmmaannccee__ccoouunntteerrss..ccpppp::4422 ****** | │ │ │ │ │ +|THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | │ │ │ │ │ +|AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | │ │ │ │ │ +|IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | │ │ │ │ │ +|ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | │ │ │ │ │ +|LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | │ │ │ │ │ +|CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | │ │ │ │ │ +|SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | │ │ │ │ │ +|INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | │ │ │ │ │ +|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ +|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ +|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ | | │ │ │ │ │ -| int idx1, idx2; | │ │ │ │ │ -|constexpr int max_index = 10000; // can't risk out of memory | │ │ │ │ │ +|*/ | │ │ │ │ │ | | │ │ │ │ │ -| auto const divider = token.find_first_of('-'); | │ │ │ │ │ -| if (divider != std::string::npos) // it's a range | │ │ │ │ │ -| { | │ │ │ │ │ -| if (divider == 0) // no start index | │ │ │ │ │ -| continue; | │ │ │ │ │ -| if (divider == token.size() - 1) // no end index | │ │ │ │ │ -| continue; | │ │ │ │ │ +|#include "libtorrent/performance_counters.hpp" | │ │ │ │ │ +|#include "libtorrent/assert.hpp" | │ │ │ │ │ +|#include // for memset | │ │ │ │ │ | | │ │ │ │ │ -| idx1 = std::atoi(token.substr(0, divider).to_string().c_str()); | │ │ │ │ │ -| if (idx1 < 0 || idx1 > max_index) // invalid index | │ │ │ │ │ -| continue; | │ │ │ │ │ -| idx2 = std::atoi(token.substr(divider + 1).to_string().c_str()); | │ │ │ │ │ -| if (idx2 < 0 || idx2 > max_index) // invalid index | │ │ │ │ │ -| continue; | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ | | │ │ │ │ │ -| if (idx1 > idx2) // wrong range limits | │ │ │ │ │ -| continue; | │ │ │ │ │ -| } | │ │ │ │ │ -| else // it's an index | │ │ │ │ │ -| { | │ │ │ │ │ -| idx1 = std::atoi(token.to_string().c_str()); | │ │ │ │ │ -| if (idx1 < 0 || idx1 > max_index) // invalid index | │ │ │ │ │ -| continue; | │ │ │ │ │ -| idx2 = idx1; | │ │ │ │ │ -| } | │ │ │ │ │ +|counters::counters() TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ +|{ | │ │ │ │ │ +|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ +| for (auto& counter : m_stats_counter) | │ │ │ │ │ +| counter.store(0, std::memory_order_relaxed); | │ │ │ │ │ +|#else | │ │ │ │ │ +| m_stats_counter.fill(0); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (int(p.file_priorities.size()) <= idx2) | │ │ │ │ │ -|_ _ _ _ _ _ _p_._f_i_l_e___p_r_i_o_r_i_t_i_e_s_._r_e_s_i_z_e_(_s_t_a_t_i_c___c_a_s_t_<_s_t_d_:_:_s_i_z_e___t_>_(_i_d_x_2_)_ _+_ _1_,_ _d_o_n_t___d_o_w_n_l_o_a_d_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| counters::counters(counters const& c) TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ +| { | │ │ │ │ │ +|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ +| for (int i = 0; i < m_stats_counter.end_index(); ++i) | │ │ │ │ │ +| m_stats_counter[i].store( | │ │ │ │ │ +| c.m_stats_counter[i].load(std::memory_order_relaxed) | │ │ │ │ │ +| , std::memory_order_relaxed); | │ │ │ │ │ +|#else | │ │ │ │ │ +| std::lock_guard l(c.m_mutex); | │ │ │ │ │ +| m_stats_counter = c.m_stats_counter; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| counters& counters::operator=(counters const& c) & TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ +| { | │ │ │ │ │ +| if (&c == this) return *this; | │ │ │ │ │ +|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ +| for (int i = 0; i < m_stats_counter.end_index(); ++i) | │ │ │ │ │ +| m_stats_counter[i].store( | │ │ │ │ │ +| c.m_stats_counter[i].load(std::memory_order_relaxed) | │ │ │ │ │ +|_ _ _ _ _ _,_ _s_t_d_:_:_m_e_m_o_r_y___o_r_d_e_r___r_e_l_a_x_e_d_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_h_a_s_h___p_i_c_k_e_r_._c_p_p_:_3_0_9_ _ _ _ _|_u_s_e_ _s_t_r_u_c_t_u_r_e_d_ _b_i_n_d_i_n_g_s_ _i_n_ _C_+_+_1_7_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** uussee ssttrruuccttuurreedd bbiinnddiinnggss iinn CC++++1177 ********** | │ │ │ │ │ |****** ....//ssrrcc//hhaasshh__ppiicckkeerr..ccpppp::330099 ****** | │ │ │ │ │ |, int const offset, sha256_hash const& h) | │ │ │ │ │ | { | │ │ │ │ │ | TORRENT_ASSERT(offset >= 0); | │ │ │ │ │ | auto const f = m_files.file_index_at_piece(piece); | │ │ │ │ │ @@ -7825,773 +8977,312 @@ │ │ │ │ │ | TORRENT_ASSERT(req.base == m_piece_layer && req.index % 512 == 0); | │ │ │ │ │ | | │ │ │ │ │ | for (int i = req.index; i < req.index + req.count; i += 512) | │ │ │ │ │ | { | │ │ │ │ │ | m_piece_hash_requested[req.file][i / 512].last_request = min_time(); | │ │ │ │ │ | --m_piece_hash_requested[req.file][i / 512].num_requests; | │ │ │ │ │ |_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t___p_e_e_r_._c_p_p_:_1_9_2_ _ _ _|_h_o_w_ _d_o_ _w_e_ _d_e_a_l_ _w_i_t_h_ _o_u_r_ _e_x_t_e_r_n_a_l_ _a_d_d_r_e_s_s_ _c_h_a_n_g_i_n_g_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** hhooww ddoo wwee ddeeaall wwiitthh oouurr eexxtteerrnnaall aaddddrreessss cchhaannggiinngg?? ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt__ppeeeerr..ccpppp::119922 ****** | │ │ │ │ │ -|// connections. If it fails, we'll | │ │ │ │ │ -| // retry with encryption | │ │ │ │ │ -| , pe_support(false) | │ │ │ │ │ -|#endif | │ │ │ │ │ -| , is_v6_addr(false) | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| , is_i2p_addr(false) | │ │ │ │ │ -|#endif | │ │ │ │ │ -| , on_parole(false) | │ │ │ │ │ -| , banned(false) | │ │ │ │ │ -| , supports_utp(true) // assume peers support utp | │ │ │ │ │ -| , confirmed_supports_utp(false) | │ │ │ │ │ -| , supports_holepunch(false) | │ │ │ │ │ -| , web_seed(false) | │ │ │ │ │ -| , protocol_v2(false) | │ │ │ │ │ -| {} | │ │ │ │ │ -| | │ │ │ │ │ -| std::uint32_t torrent_peer::rank(external_ip const& external, int external_port) const | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(in_use); | │ │ │ │ │ -|if (peer_rank == 0) | │ │ │ │ │ -|peer_rank = peer_priority( | │ │ │ │ │ -| tcp::endpoint(external.external_address(this->address()), std::uint16_t(external_port)) | │ │ │ │ │ -| , tcp::endpoint(this->address(), this->port)); | │ │ │ │ │ -| return peer_rank; | │ │ │ │ │ -| } | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_e___c_r_y_p_t_o_._c_p_p_:_6_0_ _ _ _ _ _ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _g_e_t_ _t_h_e_ _l_i_t_e_r_a_l_ _w_o_r_k_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo ggeett tthhee lliitteerraall wwoorrkkiinngg ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppee__ccrryyppttoo..ccpppp::6600 ****** | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| std::string torrent_peer::to_string() const | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(in_use); | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| if (is_i2p_addr) return dest().to_string(); | │ │ │ │ │ -|#endif // TORRENT_USE_I2P | │ │ │ │ │ -| return address().to_string(); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ | | │ │ │ │ │ -| std::int64_t torrent_peer::total_download() const | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(in_use); | │ │ │ │ │ -| if (connection != nullptr) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(prev_amount_download == 0); | │ │ │ │ │ -| return connection->statistics().total_payload_download(); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| return std::int64_t(prev_amount_download) << 10; | │ │ │ │ │ -| } | │ │ │ │ │ -|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_d_i_s_a_b_l_e_d___d_i_s_k___i_o_._c_p_p_: |it would be nice to return a valid hash of zeroes here | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_1_0_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo rreettuurrnn aa vvaalliidd hhaasshh ooff zzeerrooeess hheerree ********** | │ │ │ │ │ -|****** ....//ssrrcc//ddiissaabblleedd__ddiisskk__iioo..ccpppp::110066 ****** | │ │ │ │ │ -|}); | │ │ │ │ │ -| } | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ | | │ │ │ │ │ -| bool async_write(storage_index_t | │ │ │ │ │ -| , peer_request const& r | │ │ │ │ │ -| , char const*, std::shared_ptr | │ │ │ │ │ -| , std::function handler | │ │ │ │ │ -| , disk_job_flags_t) override | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(r.length <= default_block_size); | │ │ │ │ │ -| TORRENT_UNUSED(r); | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ | | │ │ │ │ │ -| post(m_ios, [h = std::move(handler)] { h(storage_error{}); }); | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ +|#include "libtorrent/random.hpp" | │ │ │ │ │ +|#include "libtorrent/aux_/alloca.hpp" | │ │ │ │ │ +|#include "libtorrent/pe_crypto.hpp" | │ │ │ │ │ +|#include "libtorrent/hasher.hpp" | │ │ │ │ │ | | │ │ │ │ │ -| void async_hash(storage_index_t | │ │ │ │ │ -| , piece_index_t piece, span, disk_job_flags_t | │ │ │ │ │ -| , std::function handler) override | │ │ │ │ │ -| { | │ │ │ │ │ -|post(m_ios, [h = std::move(handler), piece] { h(piece, sha1_hash{}, storage_error{}); }); | │ │ │ │ │ -|} | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ | | │ │ │ │ │ -| void async_hash2(storage_index_t, piece_index_t piece, int | │ │ │ │ │ -| , disk_job_flags_t | │ │ │ │ │ -| , std::function handler) override | │ │ │ │ │ -| { | │ │ │ │ │ -| post(m_ios, [h = std::move(handler), piece]() { h(piece, sha256_hash{}, storage_error{}); }); | │ │ │ │ │ -| } | │ │ │ │ │ +| namespace mp = boost::multiprecision; | │ │ │ │ │ | | │ │ │ │ │ -| void async_move_storage(storage_index_t | │ │ │ │ │ -| , std::string p, move_flags_t | │ │ │ │ │ -| , std::function handler) override | │ │ │ │ │ -| { | │ │ │ │ │ -| post(m_ios, [h = std::move(handler), path = std::move(p)] () mutable | │ │ │ │ │ -| { h(status_t::no_error, std::move(path), storage_error{}); }); | │ │ │ │ │ +| namespace { | │ │ │ │ │ +|key_t const dh_prime | │ │ │ │ │ +|("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63|36210000000000090563"); │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void async_release_files(storage_index_t, std::function handler) override | │ │ │ │ │ +| std::array export_key(key_t const& k) | │ │ │ │ │ | { | │ │ │ │ │ -| post(m_ios, [h = std::move(handler)] { h(); }); | │ │ │ │ │ -| } | │ │ │ │ │ +| std::array ret; | │ │ │ │ │ +| auto* begin = reinterpret_cast(ret.data()); | │ │ │ │ │ +|_ _ _s_t_d_:_:_u_i_n_t_8___t_*_ _e_n_d_ _=_ _m_p_:_:_e_x_p_o_r_t___b_i_t_s_(_k_,_ _b_e_g_i_n_,_ _8_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_e___c_r_y_p_t_o_._c_p_p_:_7_1_ _ _ _ _ _ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _b_e_ _a_b_l_e_ _t_o_ _e_x_p_o_r_t_ _t_o_ _a_ _f_i_x_e_d_ _w_i_d_t_h_ _f_i_e_l_d_,_ _s_o_ _w_e_ _w_o_u_l_d_n_'_t_ _h_a_v_e_ _t_o_ _s_h_i_f_t_ _i_t_ _l_a_t_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo bbee aabbllee ttoo eexxppoorrtt ttoo aa ffiixxeedd wwiiddtthh ffiieelldd,, ssoo wwee wwoouullddnn''tt hhaavvee ttoo sshhiifftt iitt llaatteerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppee__ccrryyppttoo..ccpppp::7711 ****** | │ │ │ │ │ +|#include "libtorrent/random.hpp" | │ │ │ │ │ +|#include "libtorrent/aux_/alloca.hpp" | │ │ │ │ │ +|#include "libtorrent/pe_crypto.hpp" | │ │ │ │ │ +|#include "libtorrent/hasher.hpp" | │ │ │ │ │ | | │ │ │ │ │ -| void async_delete_files(storage_index_t | │ │ │ │ │ -| , remove_flags_t, std::function handler) override | │ │ │ │ │ -| { | │ │ │ │ │ -| post(m_ios, [h = std::move(handler)] { h(storage_error{}); }); | │ │ │ │ │ -| } | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ | | │ │ │ │ │ -| void async_check_files(storage_index_t | │ │ │ │ │ -|_ _ _,_ _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_ _c_o_n_s_t_*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_0_4_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _f_i_e_l_d_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhiiss ffiieelldd iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::440044 ****** | │ │ │ │ │ -| return torrent_alert::message() + ": state changed to: " | │ │ │ │ │ -| + state_str[state]; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| namespace mp = boost::multiprecision; | │ │ │ │ │ | | │ │ │ │ │ -| tracker_error_alert::tracker_error_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep, int times | │ │ │ │ │ -| , protocol_version v, string_view u, operation_t const operation | │ │ │ │ │ -| , error_code const& e | │ │ │ │ │ -| , string_view m) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , times_in_row(times) | │ │ │ │ │ -| , error(e) | │ │ │ │ │ -| , op(operation) | │ │ │ │ │ -| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| , status_code(e && e.category() == http_category() ? e.value() : -1) | │ │ │ │ │ -| , msg(m) | │ │ │ │ │ -|#endif | │ │ │ │ │ -|, version(v) | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| namespace { | │ │ │ │ │ +| key_t const dh_prime | │ │ │ │ │ +| | │ │ │ │ │ +|("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63|36210000000000090563"); │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| char const* tracker_error_alert::failure_reason() const | │ │ │ │ │ +| std::array export_key(key_t const& k) | │ │ │ │ │ | { | │ │ │ │ │ -| return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ -| } | │ │ │ │ │ +| std::array ret; | │ │ │ │ │ +| auto* begin = reinterpret_cast(ret.data()); | │ │ │ │ │ +| std::uint8_t* end = mp::export_bits(k, begin, 8); | │ │ │ │ │ | | │ │ │ │ │ -| std::string tracker_error_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char ret[400]; | │ │ │ │ │ -| std::snprintf(ret, sizeof(ret), "%s %s %s \"%s\" (%d)" | │ │ │ │ │ -| , tracker_alert::message().c_str() | │ │ │ │ │ -| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ -| , convert_from_native(error.message()).c_str(), error_message() | │ │ │ │ │ -| , times_in_row); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +|if (end < begin + 96) | │ │ │ │ │ +|{ | │ │ │ │ │ +| int const len = int(end - begin); | │ │ │ │ │ +|#if defined __GNUC__ && __GNUC__ == 12 | │ │ │ │ │ +|#pragma GCC diagnostic push | │ │ │ │ │ +|#pragma GCC diagnostic ignored "-Wstringop-overflow" | │ │ │ │ │ |#endif | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| tracker_warning_alert::tracker_warning_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , string_view u, protocol_version v, string_view m) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ -|_#_i_f_ _T_O_R_R_E_N_T___A_B_I___V_E_R_S_I_O_N_ _=_=_ _1_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_3_8_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhiiss iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::443388 ****** | │ │ │ │ │ -|return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char ret[400]; | │ │ │ │ │ -| std::snprintf(ret, sizeof(ret), "%s %s %s \"%s\" (%d)" | │ │ │ │ │ -| , tracker_alert::message().c_str() | │ │ │ │ │ -| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ -| , convert_from_native(error.message()).c_str(), error_message() | │ │ │ │ │ -| , times_in_row); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| std::memmove(begin + 96 - len, begin, aux::numeric_cast(len)); | │ │ │ │ │ +|#if defined __GNUC__ && __GNUC__ == 12 | │ │ │ │ │ +|#pragma GCC diagnostic pop | │ │ │ │ │ |#endif | │ │ │ │ │ +| std::memset(begin, 0, aux::numeric_cast(96 - len)); | │ │ │ │ │ +| } | │ │ │ │ │ +| return ret; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| tracker_warning_alert::tracker_warning_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , string_view u, protocol_version v, string_view m) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| , msg(m) | │ │ │ │ │ -|#endif | │ │ │ │ │ -|, version(v) | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ -| } | │ │ │ │ │ +| void rc4_init(const unsigned char* in, std::size_t len, rc4 *state); | │ │ │ │ │ +| std::size_t rc4_encrypt(unsigned char *out, std::size_t outlen, rc4 *state); | │ │ │ │ │ | | │ │ │ │ │ -| char const* tracker_warning_alert::warning_message() const | │ │ │ │ │ +| // Set the prime P and the generator, generate local public key | │ │ │ │ │ +| dh_key_exchange::dh_key_exchange() | │ │ │ │ │ | { | │ │ │ │ │ -| return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ -| } | │ │ │ │ │ +| aux::array random_key; | │ │ │ │ │ +| aux::random_bytes({reinterpret_cast(random_key.data()) | │ │ │ │ │ +| , static_cast(random_key.size())}); | │ │ │ │ │ | | │ │ │ │ │ -| std::string tracker_warning_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| return tracker_alert::message() + (version == protocol_version::V1 ? " v1" : " v2") + " warning: " + warning_message(); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| // create local key (random) | │ │ │ │ │ +| mp::import_bits(m_dh_local_secret, random_key.begin(), random_key.end()); | │ │ │ │ │ | | │ │ │ │ │ -| scrape_reply_alert::scrape_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , int incomp, int comp, string_view u, protocol_version const v) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , incomplete(incomp) | │ │ │ │ │ -|_ _ _,_ _c_o_m_p_l_e_t_e_(_c_o_m_p_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_6_4_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhiiss iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::446644 ****** | │ │ │ │ │ -|char const* tracker_warning_alert::warning_message() const | │ │ │ │ │ -| { | │ │ │ │ │ -| return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ +| // key = (2 ^ secret) % prime | │ │ │ │ │ +|_ _ _m___d_h___l_o_c_a_l___k_e_y_ _=_ _m_p_:_:_p_o_w_m_(_k_e_y___t_(_2_)_,_ _m___d_h___l_o_c_a_l___s_e_c_r_e_t_,_ _d_h___p_r_i_m_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_l_o_a_d___t_o_r_r_e_n_t_._c_p_p_:_1_2_1_ _ _ _|_m_o_v_e_ _t_h_e_ _l_o_a_d_i_n_g_ _l_o_g_i_c_ _f_r_o_m_ _t_o_r_r_e_n_t___i_n_f_o_ _c_o_n_s_t_r_u_c_t_o_r_ _i_n_t_o_ _h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee tthhee llooaaddiinngg llooggiicc ffrroomm ttoorrrreenntt__iinnffoo ccoonnssttrruuccttoorr iinnttoo hheerree ********** | │ │ │ │ │ +|****** ....//ssrrcc//llooaadd__ttoorrrreenntt..ccpppp::112211 ****** | │ │ │ │ │ +|mask.resize(std::size_t(full_size), false); | │ │ │ │ │ +| for (int i = merkle_first_leaf(piece_layer_size) | │ │ │ │ │ +| , end = i + num_pieces; i < end; ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| mask[std::size_t(i)] = true; | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| ti->free_piece_layers(); | │ │ │ │ │ +| } | │ │ │ │ │ +| atp.info_hashes = atp.ti->info_hashes(); | │ │ │ │ │ | } | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| std::string tracker_warning_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| return tracker_alert::message() + (version == protocol_version::V1 ? " v1" : " v2") + " warning: " + warning_message(); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| add_torrent_params load_torrent_file(std::string const& filename) | │ │ │ │ │ +| { return load_torrent_file(filename, load_torrent_limits{}); } | │ │ │ │ │ +| add_torrent_params load_torrent_buffer(span buffer) | │ │ │ │ │ +| { return load_torrent_buffer(buffer, load_torrent_limits{}); } | │ │ │ │ │ +| add_torrent_params load_torrent_parsed(bdecode_node const& torrent_file) | │ │ │ │ │ +| { return load_torrent_parsed(torrent_file, load_torrent_limits{}); } | │ │ │ │ │ | | │ │ │ │ │ -| scrape_reply_alert::scrape_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , int incomp, int comp, string_view u, protocol_version const v) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , incomplete(incomp) | │ │ │ │ │ -| , complete(comp) | │ │ │ │ │ -|, version(v) | │ │ │ │ │ +|add_torrent_params load_torrent_file(std::string const& filename, load_torrent_limits const& cfg) | │ │ │ │ │ |{ | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| add_torrent_params ret; | │ │ │ │ │ +| ret.ti = std::make_shared(filename, cfg); | │ │ │ │ │ +| update_atp(ret); | │ │ │ │ │ +| return ret; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::string scrape_reply_alert::message() const | │ │ │ │ │ +| add_torrent_params load_torrent_buffer(span buffer, load_torrent_limits const& cfg) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char ret[400]; | │ │ │ │ │ -| std::snprintf(ret, sizeof(ret), "%s %s scrape reply: %d %d" | │ │ │ │ │ -| , tracker_alert::message().c_str() | │ │ │ │ │ -| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ -| , incomplete, complete); | │ │ │ │ │ +| add_torrent_params ret; | │ │ │ │ │ +| ret.ti = std::make_shared(buffer, cfg, from_span); | │ │ │ │ │ +| update_atp(ret); | │ │ │ │ │ | return ret; | │ │ │ │ │ -|#endif | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , string_view u, protocol_version const v, error_code const& e) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , error(e) | │ │ │ │ │ -| , m_msg_idx() | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| , msg(convert_from_native(e.message())) | │ │ │ │ │ -|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_4_9_3_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhiiss iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::449933 ****** | │ │ │ │ │ -|return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char ret[400]; | │ │ │ │ │ -| std::snprintf(ret, sizeof(ret), "%s %s scrape reply: %d %d" | │ │ │ │ │ -| , tracker_alert::message().c_str() | │ │ │ │ │ -| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ -| , incomplete, complete); | │ │ │ │ │ +| add_torrent_params load_torrent_parsed(bdecode_node const& torrent_file, load_torrent_limits const& cfg) | │ │ │ │ │ +| { | │ │ │ │ │ +| add_torrent_params ret; | │ │ │ │ │ +| ret.ti = std::make_shared(torrent_file, cfg); | │ │ │ │ │ +| update_atp(ret); | │ │ │ │ │ | return ret; | │ │ │ │ │ -|#endif | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , string_view u, protocol_version const v, error_code const& e) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , error(e) | │ │ │ │ │ -| , m_msg_idx() | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| , msg(convert_from_native(e.message())) | │ │ │ │ │ -|#endif | │ │ │ │ │ -|, version(v) | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ -| } | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t___i_n_f_o_._c_p_p_:_8_8_7_ _ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _b_e_ _c_o_n_s_i_d_e_r_e_d_ _a_ _f_a_i_l_u_r_e_,_ _a_n_d_ _t_h_e_ _._t_o_r_r_e_n_t_ _f_i_l_e_ _r_e_j_e_c_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd bbee ccoonnssiiddeerreedd aa ffaaiilluurree,, aanndd tthhee ..ttoorrrreenntt ffiillee rreejjeecctteedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt__iinnffoo..ccpppp::888877 ****** | │ │ │ │ │ +|std::string ext = extension(filename); | │ │ │ │ │ +| int cnt = 0; | │ │ │ │ │ +| for (;;) | │ │ │ │ │ +| { | │ │ │ │ │ +| ++cnt; | │ │ │ │ │ +| char new_ext[50]; | │ │ │ │ │ +| std::snprintf(new_ext, sizeof(new_ext), ".%d%s", cnt, ext.c_str()); | │ │ │ │ │ +| filename = base + new_ext; | │ │ │ │ │ | | │ │ │ │ │ -| scrape_failed_alert::scrape_failed_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , string_view u, string_view m) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , error(errors::tracker_failure) | │ │ │ │ │ -| , m_msg_idx(alloc.copy_string(m)) | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| , msg(m) | │ │ │ │ │ -|#endif | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ -| } | │ │ │ │ │ +| boost::crc_optimal<32, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc; | │ │ │ │ │ +| process_string_lowercase(crc, filename); | │ │ │ │ │ +| std::uint32_t const new_hash = crc.checksum(); | │ │ │ │ │ +| if (files.find(new_hash) == files.end()) | │ │ │ │ │ +| { | │ │ │ │ │ +| files.insert({new_hash, {i, 0}}); | │ │ │ │ │ +| break; | │ │ │ │ │ +| } | │ │ │ │ │ +| ++num_collisions; | │ │ │ │ │ +| if (num_collisions > 100) | │ │ │ │ │ +| { | │ │ │ │ │ +|} | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| char const* scrape_failed_alert::error_message() const | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_msg_idx == aux::allocation_slot()) return ""; | │ │ │ │ │ -| else return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ +| copy_on_write(); | │ │ │ │ │ +| m_files.rename_file(i, filename); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::string scrape_failed_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| return tracker_alert::message() + " scrape failed: " + error_message(); | │ │ │ │ │ -|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_5_3_2_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _f_i_e_l_d_ _i_n_t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhiiss ffiieelldd iinnttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::553322 ****** | │ │ │ │ │ -|char const* scrape_failed_alert::error_message() const | │ │ │ │ │ +| void torrent_info::remap_files(file_storage const& f) | │ │ │ │ │ | { | │ │ │ │ │ -| if (m_msg_idx == aux::allocation_slot()) return ""; | │ │ │ │ │ -| else return m_alloc.get().ptr(m_msg_idx); | │ │ │ │ │ -| } | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ | | │ │ │ │ │ -| std::string scrape_failed_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| return tracker_alert::message() + " scrape failed: " + error_message(); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| TORRENT_ASSERT(is_loaded()); | │ │ │ │ │ +| // the new specified file storage must have the exact | │ │ │ │ │ +| // same size as the current file storage | │ │ │ │ │ +| TORRENT_ASSERT(m_files.total_size() == f.total_size()); | │ │ │ │ │ | | │ │ │ │ │ -| tracker_reply_alert::tracker_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep | │ │ │ │ │ -| , int np, protocol_version v, string_view u) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , num_peers(np) | │ │ │ │ │ -|, version(v) | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ +| if (m_files.total_size() != f.total_size()) return; | │ │ │ │ │ +| copy_on_write(); | │ │ │ │ │ +| m_files = f; | │ │ │ │ │ +| m_files.set_num_pieces(m_orig_files->num_pieces()); | │ │ │ │ │ +| m_files.set_piece_length(m_orig_files->piece_length()); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::string tracker_reply_alert::message() const | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| // standard constructor that parses a torrent file | │ │ │ │ │ +| torrent_info::torrent_info(entry const& torrent_file) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ +| std::vector tmp; | │ │ │ │ │ +| std::back_insert_iterator> out(tmp); | │ │ │ │ │ +|_ _ _b_e_n_c_o_d_e_(_o_u_t_,_ _t_o_r_r_e_n_t___f_i_l_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___h_a_n_d_l_e_._c_p_p_:_4_9_9_ _|_i_n_ _C_+_+_1_4_,_ _u_s_e_ _u_n_i_q_u_e___p_t_r_ _a_n_d_ _m_o_v_e_ _i_t_ _i_n_t_o_ _t_h_e_ _l_a_m_b_d_a_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinn CC++++1144,, uussee uunniiqquuee__ppttrr aanndd mmoovvee iitt iinnttoo tthhee llaammbbddaa ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__hhaannddllee..ccpppp::449999 ****** | │ │ │ │ │ +|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ +| if (params.save_path.empty()) | │ │ │ │ │ +| aux::throw_ex(error_code(errors::invalid_save_path)); | │ │ │ │ │ |#else | │ │ │ │ │ -| char ret[400]; | │ │ │ │ │ -| std::snprintf(ret, sizeof(ret), "%s %s received peers: %d" | │ │ │ │ │ -| , tracker_alert::message().c_str() | │ │ │ │ │ -| , version == protocol_version::V1 ? "v1" : "v2" | │ │ │ │ │ -| , num_peers); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| TORRENT_ASSERT_PRECOND(!params.save_path.empty()); | │ │ │ │ │ |#endif | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| dht_reply_alert::dht_reply_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h | │ │ │ │ │ -| , int np) | │ │ │ │ │ -| : tracker_alert(alloc, h, {}, "") | │ │ │ │ │ -| , num_peers(np) | │ │ │ │ │ -| {} | │ │ │ │ │ -| | │ │ │ │ │ -| std::string dht_reply_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|_#_e_l_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_a_l_e_r_t_._c_p_p_:_5_7_6_ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _t_h_i_s_ _t_o_ _t_r_a_c_k_e_r___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhiiss ttoo ttrraacckkeerr__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//aalleerrtt..ccpppp::557766 ****** | │ │ │ │ │ -|, num_peers(np) | │ │ │ │ │ -| {} | │ │ │ │ │ -| | │ │ │ │ │ -| std::string dht_reply_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| char ret[400]; | │ │ │ │ │ -| std::snprintf(ret, sizeof(ret), "%s received DHT peers: %d" | │ │ │ │ │ -| , tracker_alert::message().c_str(), num_peers); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +|#if TORRENT_ABI_VERSION < 3 | │ │ │ │ │ +| if (!params.info_hashes.has_v1() && !params.info_hashes.has_v2() && !params.ti) | │ │ │ │ │ +| params.info_hashes.v1 = params.info_hash; | │ │ │ │ │ |#endif | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| tracker_announce_alert::tracker_announce_alert(aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h, tcp::endpoint const& ep, string_view u | │ │ │ │ │ -| , protocol_version const v, event_t const e) | │ │ │ │ │ -| : tracker_alert(alloc, h, ep, u) | │ │ │ │ │ -| , event(e) | │ │ │ │ │ -|, version(v) | │ │ │ │ │ -|{ | │ │ │ │ │ -| TORRENT_ASSERT(!u.empty()); | │ │ │ │ │ -| } | │ │ │ │ │ +| // the internal torrent object keeps and mutates state in the | │ │ │ │ │ +| // torrent_info object. We can't let that leak back to the client | │ │ │ │ │ +| if (params.ti) | │ │ │ │ │ +| params.ti = std::make_shared(*params.ti); | │ │ │ │ │ | | │ │ │ │ │ -| std::string tracker_announce_alert::message() const | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -| return {}; | │ │ │ │ │ -|#else | │ │ │ │ │ -| static const char* const event_str[] = {"none", "completed", "started", "stopped", "paused"}; | │ │ │ │ │ -| return tracker_alert::message() | │ │ │ │ │ -| + (version == protocol_version::V1 ? " v1" : " v2") | │ │ │ │ │ -| + " sending announce (" + event_str[static_cast(event)] + ")"; | │ │ │ │ │ +| // we cannot capture a unique_ptr into a lambda in c++11, so we use a raw | │ │ │ │ │ +| // pointer for now. async_call uses a lambda expression to post the call | │ │ │ │ │ +| // to the main thread | │ │ │ │ │ +|auto* p = new add_torrent_params(std::move(params)); | │ │ │ │ │ +|auto guard = aux::scope_end([p]{ delete p; }); | │ │ │ │ │ +| p->save_path = complete(p->save_path); | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| handle_backwards_compatible_resume_data(*p); | │ │ │ │ │ |#endif | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| hash_failed_alert::hash_failed_alert( | │ │ │ │ │ -| aux::stack_allocator& alloc | │ │ │ │ │ -| , torrent_handle const& h | │ │ │ │ │ -| , piece_index_t index) | │ │ │ │ │ -| : torrent_alert(alloc, h) | │ │ │ │ │ -| , piece_index(index) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(index >= piece_index_t(0)); | │ │ │ │ │ +| async_call(&session_impl::async_add_torrent, p); | │ │ │ │ │ +| guard.disarm(); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::string hash_failed_alert::message() const | │ │ │ │ │ +|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| // if the torrent already exists, this will throw duplicate_torrent | │ │ │ │ │ +| torrent_handle session_handle::add_torrent( | │ │ │ │ │ +| torrent_info const& ti | │ │ │ │ │ +| , std::string const& save_path | │ │ │ │ │ +| , entry const& resume_data | │ │ │ │ │ +| , storage_mode_t storage_mode | │ │ │ │ │ +| , bool const add_paused) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifdef TORRENT_DISABLE_ALERT_MSG | │ │ │ │ │ -|_ _ _r_e_t_u_r_n_ _{_}_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_r_a_n_d_o_m_._c_p_p_:_1_4_1_ _ _ _ _ _ _ _ _ _|_i_m_p_r_o_v_e_ _c_a_l_l_i_n_g_ _R_A_N_D___b_y_t_e_s_ _m_u_l_t_i_p_l_e_ _t_i_m_e_s_,_ _u_s_i_n_g_ _f_a_l_l_b_a_c_k_ _f_o_r_ _n_o_w_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iimmpprroovvee ccaalllliinngg RRAANNDD__bbyytteess mmuullttiippllee ttiimmeess,, uussiinngg ffaallllbbaacckk ffoorr nnooww ********** | │ │ │ │ │ -|****** ....//ssrrcc//rraannddoomm..ccpppp::114411 ****** | │ │ │ │ │ -|#else | │ │ │ │ │ -| std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void crypto_random_bytes(span buffer) | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_BUILD_SIMULATOR | │ │ │ │ │ -| // In the simulator we want deterministic random numbers | │ │ │ │ │ -| std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); | │ │ │ │ │ -|#elif TORRENT_USE_CNG | │ │ │ │ │ -| aux::cng_gen_random(buffer); | │ │ │ │ │ -|#elif TORRENT_USE_CRYPTOAPI | │ │ │ │ │ -| // windows | │ │ │ │ │ -| aux::crypt_gen_random(buffer); | │ │ │ │ │ -|#elif defined TORRENT_USE_LIBCRYPTO && !defined TORRENT_USE_WOLFSSL | │ │ │ │ │ -|// wolfSSL uses wc_RNG_GenerateBlock as the internal function for the | │ │ │ │ │ -|// openssl compatibility layer. This function API does not support | │ │ │ │ │ -|// an arbitrary buffer size (openssl does), it is limited by the | │ │ │ │ │ -|// constant RNG_MAX_BLOCK_LEN. | │ │ │ │ │ -| | │ │ │ │ │ -|// openssl | │ │ │ │ │ -| int r = RAND_bytes(reinterpret_cast(buffer.data()) | │ │ │ │ │ -| , int(buffer.size())); | │ │ │ │ │ -| if (r != 1) aux::throw_ex(errors::no_entropy); | │ │ │ │ │ -|#elif TORRENT_USE_GETRANDOM | │ │ │ │ │ -| ssize_t const r = ::getrandom(buffer.data(), static_cast(buffer.size()), 0); | │ │ │ │ │ -| if (r == ssize_t(buffer.size())) return; | │ │ │ │ │ -| if (r == -1 && errno != ENOSYS) aux::throw_ex(error_code(errno, generic_category())); | │ │ │ │ │ -| static dev_random dev; | │ │ │ │ │ -| dev.read(buffer); | │ │ │ │ │ -|#elif TORRENT_USE_DEV_RANDOM | │ │ │ │ │ -| static dev_random dev; | │ │ │ │ │ -| dev.read(buffer); | │ │ │ │ │ -|#else | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_BROKEN_RANDOM_DEVICE | │ │ │ │ │ -| // even pseudo random numbers rely on being able to seed the random | │ │ │ │ │ -| // generator | │ │ │ │ │ -|#error "no entropy source available" | │ │ │ │ │ -|#else | │ │ │ │ │ -|#ifdef TORRENT_I_WANT_INSECURE_RANDOM_NUMBERS | │ │ │ │ │ -| std::generate(buffer.begin(), buffer.end(), [] { return char(random(0xff)); }); | │ │ │ │ │ -|#else | │ │ │ │ │ -|#error "no secure entropy source available. If you really want insecure random numbers, define TORRENT_I_WANT_INSECURE_RANDOM_NUMBERS" | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_2_3_0 |ideally, if we end up copying files because of a move across volumes, the source should not be deleted until they've all been | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_c_o_p_i_e_d_._ _T_h_a_t_ _w_o_u_l_d_ _l_e_t_ _u_s_ _r_o_l_l_b_a_c_k_ _w_i_t_h_ _h_i_g_h_e_r_ _c_o_n_f_i_d_e_n_c_e_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iiddeeaallllyy,, iiff wwee eenndd uupp ccooppyyiinngg ffiilleess bbeeccaauussee ooff aa mmoovvee aaccrroossss vvoolluummeess,, tthhee ssoouurrccee sshhoouulldd nnoott bbee ddeelleetteedd uunnttiill tthheeyy''vvee aallll bbeeeenn ccooppiieedd.. TThhaatt wwoouulldd lleett uuss rroollllbbaacckk wwiitthh | │ │ │ │ │ -|hhiigghheerr ccoonnffiiddeennccee.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::223300 ****** | │ │ │ │ │ -|// later | │ │ │ │ │ -| aux::vector copied_files(std::size_t(f.num_files()), false); | │ │ │ │ │ -| | │ │ │ │ │ -| // track how far we got in case of an error | │ │ │ │ │ -| file_index_t file_index{}; | │ │ │ │ │ -| for (auto const i : f.file_range()) | │ │ │ │ │ +| add_torrent_params p; | │ │ │ │ │ +| p.ti = std::make_shared(ti); | │ │ │ │ │ +| p.save_path = save_path; | │ │ │ │ │ +| if (resume_data.type() != entry::undefined_t) | │ │ │ │ │ | { | │ │ │ │ │ -| // files moved out to absolute paths are not moved | │ │ │ │ │ -| if (f.file_absolute_path(i)) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| std::string const old_path = combine_path(save_path, f.file_path(i)); | │ │ │ │ │ -| std::string const new_path = combine_path(new_save_path, f.file_path(i)); | │ │ │ │ │ -| | │ │ │ │ │ -| error_code ignore; | │ │ │ │ │ -| if (flags == move_flags_t::dont_replace && exists(new_path, ignore)) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (ret == status_t::no_error) ret = status_t::need_full_check; | │ │ │ │ │ -| continue; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|move_file(old_path, new_path, ec); | │ │ │ │ │ -| | │ │ │ │ │ -| // if the source file doesn't exist. That's not a problem | │ │ │ │ │ -| // we just ignore that file | │ │ │ │ │ -| if (ec.ec == boost::system::errc::no_such_file_or_directory) | │ │ │ │ │ -| ec.ec.clear(); | │ │ │ │ │ -| else if (ec | │ │ │ │ │ -| && ec.ec != boost::system::errc::invalid_argument | │ │ │ │ │ -| && ec.ec != boost::system::errc::permission_denied) | │ │ │ │ │ -| { | │ │ │ │ │ -| // moving the file failed | │ │ │ │ │ -| // on OSX, the error when trying to rename a file across different | │ │ │ │ │ -| // volumes is EXDEV, which will make it fall back to copying. | │ │ │ │ │ -| ec.ec.clear(); | │ │ │ │ │ -| copy_file(old_path, new_path, ec); | │ │ │ │ │ -| if (!ec) copied_files[i] = true; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| if (ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| ec.file(i); | │ │ │ │ │ -| file_index = i; | │ │ │ │ │ -| break; | │ │ │ │ │ -| } | │ │ │ │ │ +| bencode(std::back_inserter(p.resume_data), resume_data); | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -| if (!ec && move_partfile) | │ │ │ │ │ -| { | │ │ │ │ │ -| error_code e; | │ │ │ │ │ -| move_partfile(new_save_path, e); | │ │ │ │ │ -|_ _ _ _i_f_ _(_e_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_s_t_o_r_a_g_e___u_t_i_l_s_._c_p_p_:_5_3_8 |it would seem reasonable to, instead, set the have_pieces bits for the pieces representing these files, and resume with the normal | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_l_o_g_i_c_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd sseeeemm rreeaassoonnaabbllee ttoo,, iinnsstteeaadd,, sseett tthhee hhaavvee__ppiieecceess bbiittss ffoorr tthhee ppiieecceess rreepprreesseennttiinngg tthheessee ffiilleess,, aanndd rreessuummee wwiitthh tthhee nnoorrmmaall llooggiicc ********** | │ │ │ │ │ -|****** ....//ssrrcc//ssttoorraaggee__uuttiillss..ccpppp::553388 ****** | │ │ │ │ │ -|continue; | │ │ │ │ │ -| | │ │ │ │ │ -| std::int64_t const size = get_filesize(stat, file_index, fs | │ │ │ │ │ -| , save_path, ec); | │ │ │ │ │ -| if (size < 0) return false; | │ │ │ │ │ -| | │ │ │ │ │ -| if (size < fs.file_size(file_index)) | │ │ │ │ │ -| { | │ │ │ │ │ -| ec.ec = errors::mismatching_file_size; | │ │ │ │ │ -| ec.file(file_index); | │ │ │ │ │ -| ec.operation = operation_t::check_resume; | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ +| p.storage_mode = storage_mode; | │ │ │ │ │ +|_ _ _i_f_ _(_a_d_d___p_a_u_s_e_d_)_ _p_._f_l_a_g_s_ _|_=_ _a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_:_:_f_l_a_g___p_a_u_s_e_d_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/ |why is this a linked list? | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_u_d_p___t_r_a_c_k_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_:_6_3_3_|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** wwhhyy iiss tthhiiss aa lliinnkkeedd lliisstt?? ********** | │ │ │ │ │ +|****** ....//ssrrcc//uuddpp__ttrraacckkeerr__ccoonnnneeccttiioonn..ccpppp::663333 ****** | │ │ │ │ │ +|ipv6_peer_entry e{}; | │ │ │ │ │ +| std::memcpy(e.ip.data(), buf.data(), 16); | │ │ │ │ │ +| buf = buf.subspan(16); | │ │ │ │ │ +| e.port = aux::read_uint16(buf); | │ │ │ │ │ +| resp.peers6.push_back(e); | │ │ │ │ │ | } | │ │ │ │ │ -| return true; | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ -| // always trigger a full recheck when we pull in files from other | │ │ │ │ │ -| // torrents, via hard links | │ │ │ │ │ -|if (added_files) return false; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| // parse have bitmask. Verify that the files we expect to have | │ │ │ │ │ -| // actually do exist | │ │ │ │ │ -| piece_index_t const end_piece = std::min(rd.have_pieces.end_index(), fs.end_piece()); | │ │ │ │ │ -| for (piece_index_t i(0); i < end_piece; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (rd.have_pieces.get_bit(i) == false) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| std::vector f = fs.map_block(i, 0, 1); | │ │ │ │ │ -| TORRENT_ASSERT(!f.empty()); | │ │ │ │ │ -| | │ │ │ │ │ -| file_index_t const file_index = f[0].file_index; | │ │ │ │ │ -| | │ │ │ │ │ -| // files with priority zero may not have been saved to disk at their | │ │ │ │ │ -| // expected location, but is likely to be in a partfile. Just exempt it | │ │ │ │ │ -| // from checking | │ │ │ │ │ -| if (file_index < file_priority.end_index() | │ │ │ │ │ -| && file_priority[file_index] == dont_download) | │ │ │ │ │ -| continue; | │ │ │ │ │ -| | │ │ │ │ │ -| if (fs.pad_file_at(file_index)) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| if (get_filesize(stat, file_index, fs, save_path, ec) < 0) | │ │ │ │ │ -| return false; | │ │ │ │ │ -| | │ │ │ │ │ -| // OK, this file existed, good. Now, skip all remaining pieces in | │ │ │ │ │ -| // this file. We're just sanity-checking whether the files exist | │ │ │ │ │ -| // or not. | │ │ │ │ │ -|_ _ _ _p_e_e_r___r_e_q_u_e_s_t_ _c_o_n_s_t_ _p_r_ _=_ _f_s_._m_a_p___f_i_l_e_(_f_i_l_e___i_n_d_e_x_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |this should be the global download rate | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_1_1_0_5_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd bbee tthhee gglloobbaall ddoowwnnllooaadd rraattee ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::11110055 ****** | │ │ │ │ │ -| int rate = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| // if we haven't received any data recently, the current download rate | │ │ │ │ │ -| // is not representative | │ │ │ │ │ -| if (aux::time_now() - m_last_piece.get(m_connect) > seconds(30) && m_download_rate_peak > 0) | │ │ │ │ │ -| { | │ │ │ │ │ -| rate = m_download_rate_peak; | │ │ │ │ │ -| } | │ │ │ │ │ -| else if (aux::time_now() - m_last_unchoked.get(m_connect) < seconds(5) | │ │ │ │ │ -| && m_statistics.total_payload_upload() < 2 * 0x4000) | │ │ │ │ │ -| { | │ │ │ │ │ -| // if we're have only been unchoked for a short period of time, | │ │ │ │ │ -| // we don't know what rate we can get from this peer. Instead of assuming | │ │ │ │ │ -| // the lowest possible rate, assume the average. | │ │ │ │ │ -| | │ │ │ │ │ -| int peers_with_requests = int(stats_counters()[counters::num_peers_down_requests]); | │ │ │ │ │ -| // avoid division by 0 | │ │ │ │ │ -| if (peers_with_requests == 0) peers_with_requests = 1; | │ │ │ │ │ -| | │ │ │ │ │ -|rate = t->statistics().transfer_rate(stat::download_payload) / peers_with_requests; | │ │ │ │ │ -|} | │ │ │ │ │ | else | │ │ │ │ │ | { | │ │ │ │ │ -| // current download rate in bytes per seconds | │ │ │ │ │ -| rate = m_statistics.transfer_rate(stat::download_payload); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // avoid division by zero | │ │ │ │ │ -| if (rate < 50) rate = 50; | │ │ │ │ │ -| | │ │ │ │ │ -| // average of current rate and peak | │ │ │ │ │ -|// rate = (rate + m_download_rate_peak) / 2; | │ │ │ │ │ -| | │ │ │ │ │ -| return milliseconds((m_outstanding_bytes + extra_bytes | │ │ │ │ │ -| + m_queued_time_critical * t->block_size() * 1000) / rate); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void peer_connection::add_stat(std::int64_t const downloaded, std::int64_t const uploaded) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| m_statistics.add_stat(downloaded, uploaded); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| sha1_hash peer_connection::associated_info_hash() const | │ │ │ │ │ -| { | │ │ │ │ │ -| std::shared_ptr t = associated_torrent().lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -| auto const& ih = t->info_hash(); | │ │ │ │ │ -| // if protocol_v2 is set on the peer, this better be a v2 torrent, | │ │ │ │ │ -|_ _ _/_/_ _o_t_h_e_r_w_i_s_e_ _s_o_m_e_t_h_i_n_g_ _i_s_n_'_t_ _r_i_g_h_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._c_p_p_: |sort the allowed fast set in priority order | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_3_5_3_6_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssoorrtt tthhee aalllloowweedd ffaasstt sseett iinn pprriioorriittyy oorrddeerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeeeerr__ccoonnnneeccttiioonn..ccpppp::33553366 ****** | │ │ │ │ │ -| // if the peer has the piece and we want | │ │ │ │ │ -| // to download it, request it | │ │ │ │ │ -| if (index < m_have_piece.end_index() | │ │ │ │ │ -| && m_have_piece[index] | │ │ │ │ │ -| && !t->have_piece(index) | │ │ │ │ │ -| && t->valid_metadata() | │ │ │ │ │ -| && t->has_picker() | │ │ │ │ │ -| && t->picker().piece_priority(index) > dont_download) | │ │ │ │ │ -| { | │ │ │ │ │ -| t->peer_is_interesting(*this); | │ │ │ │ │ +| resp.peers4.reserve(static_cast(num_peers)); | │ │ │ │ │ +| for (int i = 0; i < num_peers; ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| ipv4_peer_entry e{}; | │ │ │ │ │ +| std::memcpy(e.ip.data(), buf.data(), 4); | │ │ │ │ │ +| buf = buf.subspan(4); | │ │ │ │ │ +| e.port = aux::read_uint16(buf); | │ │ │ │ │ +| resp.peers4.push_back(e); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| std::vector const& peer_connection::allowed_fast() | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -| | │ │ │ │ │ -|return m_allowed_fast; | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| bool peer_connection::can_request_time_critical() const | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| if (has_peer_choked() || !is_interesting()) return false; | │ │ │ │ │ -| if (int(m_download_queue.size()) + int(m_request_queue.size()) | │ │ │ │ │ -| > m_desired_queue_size * 2) return false; | │ │ │ │ │ -| if (on_parole()) return false; | │ │ │ │ │ -| if (m_disconnecting) return false; | │ │ │ │ │ -| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -| if (t->upload_mode()) return false; | │ │ │ │ │ -| | │ │ │ │ │ -| // ignore snubbed peers, since they're not likely to return pieces in a | │ │ │ │ │ -| // timely manner anyway | │ │ │ │ │ -| if (m_snubbed) return false; | │ │ │ │ │ -| return true; | │ │ │ │ │ -| } | │ │ │ │ │ | | │ │ │ │ │ -| bool peer_connection::make_time_critical(piece_block const& block) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| auto const rit = std::find_if(m_request_queue.begin() | │ │ │ │ │ -| , m_request_queue.end(), aux::has_block(block)); | │ │ │ │ │ -| if (rit == m_request_queue.end()) return false; | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -| std::shared_ptr t = m_torrent.lock(); | │ │ │ │ │ -| TORRENT_ASSERT(t); | │ │ │ │ │ -|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T_(_t_-_>_h_a_s___p_i_c_k_e_r_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/ |move stats_counter_t out of counters | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._c_p_p_:_4_0_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee ssttaattss__ccoouunntteerr__tt oouutt ooff ccoouunntteerrss ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_ss_rr_cc_//_pp_ee_rr_ff_oo_rr_mm_aa_nn_cc_ee____cc_oo_uu_nn_tt_ee_rr_ss_.._cc_pp_pp_::_44_00_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/ |should bittorrent keep-alive messages have a counter too? | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._c_p_p_:_4_1_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** sshhoouulldd bbiittttoorrrreenntt kkeeeepp--aalliivvee mmeessssaaggeess hhaavvee aa ccoouunntteerr ttoooo?? ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_ss_rr_cc_//_pp_ee_rr_ff_oo_rr_mm_aa_nn_cc_ee____cc_oo_uu_nn_tt_ee_rr_ss_.._cc_pp_pp_::_44_11_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/ |It would be nice if this could be an internal type. default_disk_constructor depends on it now | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._c_p_p_:_4_2_ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** IItt wwoouulldd bbee nniiccee iiff tthhiiss ccoouulldd bbee aann iinntteerrnnaall ttyyppee.. ddeeffaauulltt__ddiisskk__ccoonnssttrruuccttoorr ddeeppeennddss oonn iitt nnooww ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppeerrffoorrmmaannccee__ccoouunntteerrss..ccpppp::4422 ****** | │ │ │ │ │ -|THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | │ │ │ │ │ -|AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | │ │ │ │ │ -|IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | │ │ │ │ │ -|ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | │ │ │ │ │ -|LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | │ │ │ │ │ -|CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | │ │ │ │ │ -|SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | │ │ │ │ │ -|INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | │ │ │ │ │ -|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ -|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ -|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ -| | │ │ │ │ │ -|*/ | │ │ │ │ │ -| | │ │ │ │ │ -|#include "libtorrent/performance_counters.hpp" | │ │ │ │ │ -|#include "libtorrent/assert.hpp" | │ │ │ │ │ -|#include // for memset | │ │ │ │ │ +|std::list
    ip_list; | │ │ │ │ │ +|std::transform(m_endpoints.begin(), m_endpoints.end(), std::back_inserter(ip_list) | │ │ │ │ │ +| , [](tcp::endpoint const& ep) { return ep.address(); } ); | │ │ │ │ │ | | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ +| cb->tracker_response(tracker_req(), m_target.address(), ip_list, resp); | │ │ │ │ │ | | │ │ │ │ │ -|counters::counters() TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ -|{ | │ │ │ │ │ -|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ -| for (auto& counter : m_stats_counter) | │ │ │ │ │ -| counter.store(0, std::memory_order_relaxed); | │ │ │ │ │ -|#else | │ │ │ │ │ -| m_stats_counter.fill(0); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| close(); | │ │ │ │ │ +| return true; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| counters::counters(counters const& c) TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ +| bool udp_tracker_connection::on_scrape_response(span buf) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ -| for (int i = 0; i < m_stats_counter.end_index(); ++i) | │ │ │ │ │ -| m_stats_counter[i].store( | │ │ │ │ │ -| c.m_stats_counter[i].load(std::memory_order_relaxed) | │ │ │ │ │ -| , std::memory_order_relaxed); | │ │ │ │ │ -|#else | │ │ │ │ │ -| std::lock_guard l(c.m_mutex); | │ │ │ │ │ -| m_stats_counter = c.m_stats_counter; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| restart_read_timeout(); | │ │ │ │ │ +| auto const action = static_cast(aux::read_int32(buf)); | │ │ │ │ │ +| std::uint32_t const transaction = aux::read_uint32(buf); | │ │ │ │ │ | | │ │ │ │ │ -| counters& counters::operator=(counters const& c) & TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ -| { | │ │ │ │ │ -| if (&c == this) return *this; | │ │ │ │ │ -|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ -| for (int i = 0; i < m_stats_counter.end_index(); ++i) | │ │ │ │ │ -| m_stats_counter[i].store( | │ │ │ │ │ -| c.m_stats_counter[i].load(std::memory_order_relaxed) | │ │ │ │ │ -|_ _ _ _ _ _,_ _s_t_d_:_:_m_e_m_o_r_y___o_r_d_e_r___r_e_l_a_x_e_d_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| if (transaction != m_transaction_id) | │ │ │ │ │ +| { | │ │ │ │ │ +| fail(error_code(errors::invalid_tracker_transaction_id), operation_t::bittorrent); | │ │ │ │ │ +| return false; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| if (action == action_t::error) | │ │ │ │ │ +| { | │ │ │ │ │ +| fail(error_code(errors::tracker_failure), operation_t::bittorrent | │ │ │ │ │ +| , std::string(buf.data(), static_cast(buf.size())).c_str()); | │ │ │ │ │ +| return true; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| if (action != action_t::scrape) | │ │ │ │ │ +|_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_i_e_c_e___p_i_c_k_e_r_._c_p_p_:_1_2_1_ _ _ _|_f_i_n_d_ _a_ _b_e_t_t_e_r_ _p_l_a_c_e_ _f_o_r_ _t_h_i_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** ffiinndd aa bbeetttteerr ppllaaccee ffoorr tthhiiss ********** | │ │ │ │ │ |****** ....//ssrrcc//ppiieeccee__ppiicckkeerr..ccpppp::112211 ****** | │ │ │ │ │ |if (limit == 0) | │ │ │ │ │ | { | │ │ │ │ │ | std::cerr << " ..."; | │ │ │ │ │ | break; | │ │ │ │ │ @@ -8852,14 +9543,68 @@ │ │ │ │ │ | TORRENT_ASSERT(!m_piece_map[block.piece_index].have()); | │ │ │ │ │ | | │ │ │ │ │ | piece_pos& p = m_piece_map[block.piece_index]; | │ │ │ │ │ | if (p.download_queue() == piece_pos::piece_open) | │ │ │ │ │ | { | │ │ │ │ │ |#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS | │ │ │ │ │ |_ _ _ _I_N_V_A_R_I_A_N_T___C_H_E_C_K_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t___p_e_e_r_._c_p_p_:_1_9_2_ _ _ _|_h_o_w_ _d_o_ _w_e_ _d_e_a_l_ _w_i_t_h_ _o_u_r_ _e_x_t_e_r_n_a_l_ _a_d_d_r_e_s_s_ _c_h_a_n_g_i_n_g_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** hhooww ddoo wwee ddeeaall wwiitthh oouurr eexxtteerrnnaall aaddddrreessss cchhaannggiinngg?? ********** | │ │ │ │ │ +|****** ....//ssrrcc//ttoorrrreenntt__ppeeeerr..ccpppp::119922 ****** | │ │ │ │ │ +|// connections. If it fails, we'll | │ │ │ │ │ +| // retry with encryption | │ │ │ │ │ +| , pe_support(false) | │ │ │ │ │ +|#endif | │ │ │ │ │ +| , is_v6_addr(false) | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| , is_i2p_addr(false) | │ │ │ │ │ +|#endif | │ │ │ │ │ +| , on_parole(false) | │ │ │ │ │ +| , banned(false) | │ │ │ │ │ +| , supports_utp(true) // assume peers support utp | │ │ │ │ │ +| , confirmed_supports_utp(false) | │ │ │ │ │ +| , supports_holepunch(false) | │ │ │ │ │ +| , web_seed(false) | │ │ │ │ │ +| , protocol_v2(false) | │ │ │ │ │ +| {} | │ │ │ │ │ +| | │ │ │ │ │ +| std::uint32_t torrent_peer::rank(external_ip const& external, int external_port) const | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(in_use); | │ │ │ │ │ +|if (peer_rank == 0) | │ │ │ │ │ +|peer_rank = peer_priority( | │ │ │ │ │ +| tcp::endpoint(external.external_address(this->address()), std::uint16_t(external_port)) | │ │ │ │ │ +| , tcp::endpoint(this->address(), this->port)); | │ │ │ │ │ +| return peer_rank; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| std::string torrent_peer::to_string() const | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(in_use); | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| if (is_i2p_addr) return dest().to_string(); | │ │ │ │ │ +|#endif // TORRENT_USE_I2P | │ │ │ │ │ +| return address().to_string(); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| std::int64_t torrent_peer::total_download() const | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(in_use); | │ │ │ │ │ +| if (connection != nullptr) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(prev_amount_download == 0); | │ │ │ │ │ +| return connection->statistics().total_payload_download(); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| return std::int64_t(prev_amount_download) << 10; | │ │ │ │ │ +| } | │ │ │ │ │ +|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_c_r_e_a_t_e___t_o_r_r_e_n_t_._c_p_p_:_6_1_8_ _|_t_h_i_s_ _c_a_n_ _b_e_ _o_p_t_i_m_i_z_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** tthhiiss ccaann bbee ooppttiimmiizzeedd ********** | │ │ │ │ │ |****** ....//ssrrcc//ccrreeaattee__ttoorrrreenntt..ccpppp::661188 ****** | │ │ │ │ │ |std::string& attr = e["attr"].string(); | │ │ │ │ │ | if (flags & file_storage::flag_pad_file) attr += 'p'; | │ │ │ │ │ | if (flags & file_storage::flag_hidden) attr += 'h'; | │ │ │ │ │ | if (flags & file_storage::flag_executable) attr += 'x'; | │ │ │ │ │ @@ -8906,1624 +9651,879 @@ │ │ │ │ │ | | │ │ │ │ │ | if (!m_nodes.empty()) | │ │ │ │ │ | { | │ │ │ │ │ | entry& nodes = dict["nodes"]; | │ │ │ │ │ | entry::list_type& nodes_list = nodes.list(); | │ │ │ │ │ | for (auto const& n : m_nodes) | │ │ │ │ │ |_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_9_5_1_ _ _ _ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _o_p_t_i_m_i_z_e_d_ _b_y_ _l_o_o_k_i_n_g_ _u_p_ _w_h_i_c_h_ _f_i_l_e_s_ _a_r_e_ _c_o_m_p_l_e_t_e_ _a_n_d_ _j_u_s_t_ _l_o_o_k_ _a_t_ _t_h_o_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ccoouulldd bbee ooppttiimmiizzeedd bbyy llooookkiinngg uupp wwhhiicchh ffiilleess aarree ccoommpplleettee aanndd jjuusstt llooookk aatt tthhoossee ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11995511 ****** | │ │ │ │ │ -|// TORRENT_ASSERT(picker().have_piece(i)); | │ │ │ │ │ -| we_have(i); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| set_state(torrent_status::checking_resume_data); | │ │ │ │ │ -| | │ │ │ │ │ -| aux::vector links; | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ -| if (!m_torrent_file->similar_torrents().empty() | │ │ │ │ │ -| || !m_torrent_file->collections().empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| resolve_links res(m_torrent_file); | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const& ih : m_torrent_file->similar_torrents()) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::shared_ptr t = m_ses.find_torrent(info_hash_t(ih)).lock(); | │ │ │ │ │ -| if (!t) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| // Only attempt to reuse files from torrents that are seeding. | │ │ │ │ │ -|if (!t->is_seed()) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| res.match(t->get_torrent_file(), t->save_path()); | │ │ │ │ │ -| } | │ │ │ │ │ -| for (auto const& c : m_torrent_file->collections()) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::vector> ts = m_ses.find_collection(c); | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const& t : ts) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _ _ _/_/_ _O_n_l_y_ _a_t_t_e_m_p_t_ _t_o_ _r_e_u_s_e_ _f_i_l_e_s_ _f_r_o_m_ _t_o_r_r_e_n_t_s_ _t_h_a_t_ _a_r_e_ _s_e_e_d_i_n_g_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_9_6_4_ _ _ _ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _o_p_t_i_m_i_z_e_d_ _b_y_ _l_o_o_k_i_n_g_ _u_p_ _w_h_i_c_h_ _f_i_l_e_s_ _a_r_e_ _c_o_m_p_l_e_t_e_ _a_n_d_ _j_u_s_t_ _l_o_o_k_ _a_t_ _t_h_o_s_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ccoouulldd bbee ooppttiimmiizzeedd bbyy llooookkiinngg uupp wwhhiicchh ffiilleess aarree ccoommpplleettee aanndd jjuusstt llooookk aatt tthhoossee ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::11996644 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| resolve_links res(m_torrent_file); | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const& ih : m_torrent_file->similar_torrents()) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::shared_ptr t = m_ses.find_torrent(info_hash_t(ih)).lock(); | │ │ │ │ │ -| if (!t) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| // Only attempt to reuse files from torrents that are seeding. | │ │ │ │ │ -| if (!t->is_seed()) continue; | │ │ │ │ │ -| | │ │ │ │ │ -| res.match(t->get_torrent_file(), t->save_path()); | │ │ │ │ │ -| } | │ │ │ │ │ -| for (auto const& c : m_torrent_file->collections()) | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_a_g_n_e_t___u_r_i_._c_p_p_:_4_3_9_ _ _ _ _ _|_w_h_a_t_'_s_ _t_h_e_ _r_i_g_h_t_ _n_u_m_b_e_r_ _h_e_r_e_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** wwhhaatt''ss tthhee rriigghhtt nnuummbbeerr hheerree?? ********** | │ │ │ │ │ +|****** ....//ssrrcc//mmaaggnneett__uurrii..ccpppp::443399 ****** | │ │ │ │ │ +|} | │ │ │ │ │ +| else if (string_equal_no_case(name, "so"_sv)) // select-only (files) | │ │ │ │ │ | { | │ │ │ │ │ -| std::vector> ts = m_ses.find_collection(c); | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const& t : ts) | │ │ │ │ │ -| { | │ │ │ │ │ -| // Only attempt to reuse files from torrents that are seeding. | │ │ │ │ │ -|if (!t->is_seed()) continue; | │ │ │ │ │ +| // accept only digits, '-' and ',' | │ │ │ │ │ +| if (std::any_of(value.begin(), value.end(), [](char c) | │ │ │ │ │ +| { return !is_digit(c) && c != '-' && c != ','; })) | │ │ │ │ │ +| continue; | │ │ │ │ │ | | │ │ │ │ │ -| res.match(t->get_torrent_file(), t->save_path()); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ +| // make sure all file priorities are set to 0, except the ones | │ │ │ │ │ +| // we specify in the file_priorities | │ │ │ │ │ +| p.flags |= torrent_flags::default_dont_download; | │ │ │ │ │ | | │ │ │ │ │ -| std::vector const& l = res.get_links(); | │ │ │ │ │ -| if (!l.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| links.resize(m_torrent_file->files().num_files()); | │ │ │ │ │ -| for (auto const& i : l) | │ │ │ │ │ +| do | │ │ │ │ │ | { | │ │ │ │ │ -| if (!i.ti) continue; | │ │ │ │ │ -| links[i.file_idx] = combine_path(i.save_path | │ │ │ │ │ -| , i.ti->files().file_path(i.file_idx)); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif // TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS | │ │ │ │ │ -| TORRENT_ASSERT(m_outstanding_check_files == false); | │ │ │ │ │ -| m_outstanding_check_files = true; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (!m_add_torrent_params || !(m_add_torrent_params->flags & torrent_flags::no_verify_files)) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_ses.disk_thread().async_check_files( | │ │ │ │ │ -| m_storage, m_add_torrent_params ? m_add_torrent_params.get() : nullptr | │ │ │ │ │ -| , std::move(links), [self = shared_from_this()](status_t st, storage_error const& error) | │ │ │ │ │ -|_ _ _ _ _{_ _s_e_l_f_-_>_o_n___r_e_s_u_m_e___d_a_t_a___c_h_e_c_k_e_d_(_s_t_,_ _e_r_r_o_r_)_;_ _}_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_2_7_2_8 |this pattern is repeated in a few places. Factor this into a function and generalize the concept of a torrent having a dedicated | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_l_i_s_t_e_n_ _p_o_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ppaatttteerrnn iiss rreeppeeaatteedd iinn aa ffeeww ppllaacceess.. FFaaccttoorr tthhiiss iinnttoo aa ffuunnccttiioonn aanndd ggeenneerraalliizzee tthhee ccoonncceepptt ooff aa ttoorrrreenntt hhaavviinngg aa ddeeddiiccaatteedd lliisstteenn ppoorrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::22772288 ****** | │ │ │ │ │ -|// not ready for peers. Except, if we don't have metadata, | │ │ │ │ │ -| // we need peers to download from | │ │ │ │ │ -| if (!m_files_checked && valid_metadata()) return; | │ │ │ │ │ -| | │ │ │ │ │ -| if (!m_announce_to_lsd) return; | │ │ │ │ │ +| string_view token; | │ │ │ │ │ +| std::tie(token, value) = split_string(value, ','); | │ │ │ │ │ | | │ │ │ │ │ -| // private torrents are never announced on LSD | │ │ │ │ │ -| if (m_torrent_file->is_valid() && m_torrent_file->priv()) return; | │ │ │ │ │ +| if (token.empty()) continue; | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| // i2p torrents are also never announced on LSD | │ │ │ │ │ -| // unless we allow mixed swarms | │ │ │ │ │ -| if (is_i2p() && !settings().get_bool(settings_pack::allow_i2p_mixed)) | │ │ │ │ │ -| return; | │ │ │ │ │ -|#endif | │ │ │ │ │ +| int idx1, idx2; | │ │ │ │ │ +|constexpr int max_index = 10000; // can't risk out of memory | │ │ │ │ │ | | │ │ │ │ │ -| if (is_paused()) return; | │ │ │ │ │ +| auto const divider = token.find_first_of('-'); | │ │ │ │ │ +| if (divider != std::string::npos) // it's a range | │ │ │ │ │ +| { | │ │ │ │ │ +| if (divider == 0) // no start index | │ │ │ │ │ +| continue; | │ │ │ │ │ +| if (divider == token.size() - 1) // no end index | │ │ │ │ │ +| continue; | │ │ │ │ │ | | │ │ │ │ │ -| if (!m_ses.has_lsd()) return; | │ │ │ │ │ +| idx1 = std::atoi(token.substr(0, divider).to_string().c_str()); | │ │ │ │ │ +| if (idx1 < 0 || idx1 > max_index) // invalid index | │ │ │ │ │ +| continue; | │ │ │ │ │ +| idx2 = std::atoi(token.substr(divider + 1).to_string().c_str()); | │ │ │ │ │ +| if (idx2 < 0 || idx2 > max_index) // invalid index | │ │ │ │ │ +| continue; | │ │ │ │ │ | | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -|int port = is_ssl_torrent() ? m_ses.ssl_listen_port() : m_ses.listen_port(); | │ │ │ │ │ -|#else | │ │ │ │ │ -| int port = m_ses.listen_port(); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| if (idx1 > idx2) // wrong range limits | │ │ │ │ │ +| continue; | │ │ │ │ │ +| } | │ │ │ │ │ +| else // it's an index | │ │ │ │ │ +| { | │ │ │ │ │ +| idx1 = std::atoi(token.to_string().c_str()); | │ │ │ │ │ +| if (idx1 < 0 || idx1 > max_index) // invalid index | │ │ │ │ │ +| continue; | │ │ │ │ │ +| idx2 = idx1; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // announce with the local discovery service | │ │ │ │ │ -| m_torrent_file->info_hashes().for_each([&](sha1_hash const& ih, protocol_version) | │ │ │ │ │ -| { | │ │ │ │ │ -| m_ses.announce_lsd(ih, port); | │ │ │ │ │ -| }); | │ │ │ │ │ +| if (int(p.file_priorities.size()) <= idx2) | │ │ │ │ │ +|_ _ _ _ _ _ _p_._f_i_l_e___p_r_i_o_r_i_t_i_e_s_._r_e_s_i_z_e_(_s_t_a_t_i_c___c_a_s_t_<_s_t_d_:_:_s_i_z_e___t_>_(_i_d_x_2_)_ _+_ _1_,_ _d_o_n_t___d_o_w_n_l_o_a_d_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_6_1_5_ _ _ _|_c_o_m_e_ _u_p_ _w_i_t_h_ _s_o_m_e_ _a_b_s_t_r_a_c_t_i_o_n_ _t_o_ _d_o_ _t_h_i_s_ _f_o_r_ _g_n_u_t_l_s_ _a_s_ _w_e_l_l_ _l_o_a_d_ _c_e_r_t_i_f_i_c_a_t_e_s_ _f_r_o_m_ _t_h_e_ _w_i_n_d_o_w_s_ _s_y_s_t_e_m_ _c_e_r_t_i_f_i_c_a_t_e_ _s_t_o_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ccoommee uupp wwiitthh ssoommee aabbssttrraaccttiioonn ttoo ddoo tthhiiss ffoorr ggnnuuttllss aass wweellll llooaadd cceerrttiiffiiccaatteess ffrroomm tthhee wwiinnddoowwss ssyysstteemm cceerrttiiffiiccaattee ssttoorree ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::661155 ****** | │ │ │ │ │ +|pause(); | │ │ │ │ │ | } | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| | │ │ │ │ │ -| void torrent::dht_announce() | │ │ │ │ │ +| // This function is called by the creating thread, not in the message loop's | │ │ │ │ │ +| // io_context thread. | │ │ │ │ │ +| void session_impl::start_session() | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| if (!m_ses.dht()) | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| debug_log("DHT: no dht initialized"); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| return; | │ │ │ │ │ -| } | │ │ │ │ │ -| if (!should_announce_dht()) | │ │ │ │ │ -| { | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -|_#_i_f_ _T_O_R_R_E_N_T___U_S_E___I_2_P_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_3_8_8_5_ _ _ _ _ _ _ _|_a_d_d_ _o_n_e_ _p_e_e_r_ _p_e_r_ _I_P_ _t_h_e_ _h_o_s_t_n_a_m_e_ _r_e_s_o_l_v_e_s_ _t_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aadddd oonnee ppeeeerr ppeerr IIPP tthhee hhoossttnnaammee rreessoollvveess ttoo ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::33888855 ****** | │ │ │ │ │ -|catch (...) { handle_exception(); } | │ │ │ │ │ +| session_log("start session"); | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::on_peer_name_lookup(error_code const& e | │ │ │ │ │ -| , std::vector
    const& host_list, int const port | │ │ │ │ │ -| , protocol_version const v) try | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| | │ │ │ │ │ -| COMPLETE_ASYNC("torrent::on_peer_name_lookup"); | │ │ │ │ │ -| | │ │ │ │ │ +|#if TORRENT_USE_SSL | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| m_ssl_ctx.set_default_verify_paths(ec); | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (e && should_log()) | │ │ │ │ │ -| debug_log("peer name lookup error: %s", e.message().c_str()); | │ │ │ │ │ +| if (ec) session_log("SSL set_default verify_paths failed: %s", ec.message().c_str()); | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ |#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (e || m_abort || host_list.empty() || m_ses.is_aborted()) return; | │ │ │ │ │ -| | │ │ │ │ │ -|tcp::endpoint host(host_list.front(), std::uint16_t(port)); | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_ip_filter && m_ip_filter->access(host.address()) & ip_filter::blocked) | │ │ │ │ │ +|#if defined TORRENT_WINDOWS && defined TORRENT_USE_OPENSSL && !defined TORRENT_WINRT | │ │ │ │ │ +|X509_STORE* store = X509_STORE_new(); | │ │ │ │ │ +|if (store) | │ │ │ │ │ | { | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ +| HCERTSTORE system_store = CertOpenSystemStoreA(0, "ROOT"); | │ │ │ │ │ +| // this is best effort | │ │ │ │ │ +| if (system_store) | │ │ │ │ │ | { | │ │ │ │ │ -| debug_log("blocked ip from tracker: %s", host.address().to_string().c_str()); | │ │ │ │ │ +| CERT_CONTEXT const* ctx = nullptr; | │ │ │ │ │ +| while ((ctx = CertEnumCertificatesInStore(system_store, ctx)) != nullptr) | │ │ │ │ │ +| { | │ │ │ │ │ +| unsigned char const* cert_ptr = reinterpret_cast(ctx->pbCertEncoded); | │ │ │ │ │ +| X509* x509 = d2i_X509(nullptr, &cert_ptr, ctx->cbCertEncoded); | │ │ │ │ │ +| // this is best effort | │ │ │ │ │ +| if (!x509) continue; | │ │ │ │ │ +| X509_STORE_add_cert(store, x509); | │ │ │ │ │ +| X509_free(x509); | │ │ │ │ │ +| } | │ │ │ │ │ +| CertFreeCertificateContext(ctx); | │ │ │ │ │ +| CertCloseStore(system_store, 0); | │ │ │ │ │ | } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| if (m_ses.alerts().should_post()) | │ │ │ │ │ -| m_ses.alerts().emplace_alert(get_handle() | │ │ │ │ │ -| , host, peer_blocked_alert::ip_filter); | │ │ │ │ │ -| return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (add_peer(host, peer_info::tracker, v == protocol_version::V2 ? pex_lt_v2 : pex_flags_t(0))) | │ │ │ │ │ -| { | │ │ │ │ │ -| state_updated(); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -| debug_log("name-lookup add_peer() [ %s ] connect-candidates: %d" | │ │ │ │ │ -| , host.address().to_string().c_str() | │ │ │ │ │ -| , m_peer_list ? m_peer_list->num_connect_candidates() : -1); | │ │ │ │ │ -| } | │ │ │ │ │ +| SSL_CTX* ssl_ctx = m_ssl_ctx.native_handle(); | │ │ │ │ │ +| SSL_CTX_set_cert_store(ssl_ctx, store); | │ │ │ │ │ |#endif | │ │ │ │ │ +|#ifdef __APPLE__ | │ │ │ │ │ +| m_ssl_ctx.load_verify_file("/etc/ssl/cert.pem", ec); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (ec) session_log("SSL load_verify_file failed: %s", ec.message().c_str()); | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_1_4_8_4_ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _r_e_s_e_r_v_e_(_)_ _t_h_e_s_e_ _v_e_c_t_o_r_s_ _u_p_ _f_r_o_n_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo rreesseerrvvee(()) tthheessee vveeccttoorrss uupp ffrroonntt ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::11448844 ****** | │ │ │ │ │ +|bandwidth_channel* ch = &p->channel[peer_connection::download_channel]; | │ │ │ │ │ +| if (use_quota_overhead(ch, amount_down)) | │ │ │ │ │ +| ret |= 1 << peer_connection::download_channel; | │ │ │ │ │ +| ch = &p->channel[peer_connection::upload_channel]; | │ │ │ │ │ +| if (use_quota_overhead(ch, amount_up)) | │ │ │ │ │ +| ret |= 1 << peer_connection::upload_channel; | │ │ │ │ │ | } | │ │ │ │ │ -| update_want_peers(); | │ │ │ │ │ -|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_4_5_8_1_ _ _ _ _ _ _ _|_o_n_l_y_ _d_o_ _t_h_i_s_ _i_f_ _t_h_e_ _p_i_e_c_e_ _s_i_z_e_ _>_ _1_ _b_l_o_c_k_s_ _T_h_i_s_ _i_s_ _a_ _v_2_ _t_o_r_r_e_n_t_ _s_o_ _w_e_ _c_a_n_ _r_e_q_u_e_s_t_ _g_e_t_ _b_l_o_c_k_ _l_e_v_e_l_ _h_a_s_h_e_s_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** oonnllyy ddoo tthhiiss iiff tthhee ppiieeccee ssiizzee >> 11 bblloocckkss TThhiiss iiss aa vv22 ttoorrrreenntt ssoo wwee ccaann rreeqquueesstt ggeett bblloocckk lleevveell hhaasshheess.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::44558811 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| std::set ret; | │ │ │ │ │ -| if (!blocks.empty() && !downloaders.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| for (auto const b : blocks) ret.insert(downloaders[std::size_t(b)]); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| std::copy(downloaders.begin(), downloaders.end(), std::inserter(ret, ret.begin())); | │ │ │ │ │ -| } | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| }(); | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // if this piece wasn't downloaded from peers, we just found it on disk. | │ │ │ │ │ -| // In that case, we should just consider it as "not-have" and there's no | │ │ │ │ │ -| // need to try to get higher fidelity hashes (yet) | │ │ │ │ │ -| bool const found_on_disk = peers.size() == 1 && peers.count(nullptr); | │ │ │ │ │ +| // session_impl is responsible for deleting 'pack' | │ │ │ │ │ +| void session_impl::apply_settings_pack(std::shared_ptr pack) | │ │ │ │ │ +| { | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +| apply_settings_pack_impl(*pack); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (!torrent_file().info_hashes().has_v1() && blocks.empty() && !found_on_disk) | │ │ │ │ │ +| settings_pack session_impl::get_settings() const | │ │ │ │ │ +| { | │ │ │ │ │ +| settings_pack ret; | │ │ │ │ │ +|for (int i = settings_pack::string_type_base; | │ │ │ │ │ +|i < settings_pack::max_string_setting_internal; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -|verify_block_hashes(index); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| // the below code is penalizing peers that sent use bad data. | │ │ │ │ │ -| // increase the total amount of failed bytes | │ │ │ │ │ -| if (!found_on_disk) | │ │ │ │ │ +| ret.set_str(i, m_settings.get_str(i)); | │ │ │ │ │ +| } | │ │ │ │ │ +| for (int i = settings_pack::int_type_base; | │ │ │ │ │ +| i < settings_pack::max_int_setting_internal; ++i) | │ │ │ │ │ | { | │ │ │ │ │ -| if (blocks.empty()) | │ │ │ │ │ -| add_failed_bytes(m_torrent_file->piece_size(index)); | │ │ │ │ │ -| else | │ │ │ │ │ -| add_failed_bytes(static_cast(blocks.size()) * default_block_size); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_EXTENSIONS | │ │ │ │ │ -| for (auto& ext : m_extensions) | │ │ │ │ │ -| { | │ │ │ │ │ -| ext->on_piece_failed(index); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ +| ret.set_int(i, m_settings.get_int(i)); | │ │ │ │ │ +| } | │ │ │ │ │ +| for (int i = settings_pack::bool_type_base; | │ │ │ │ │ +| i < settings_pack::max_bool_setting_internal; ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| ret.set_bool(i, m_settings.get_bool(i)); | │ │ │ │ │ +| } | │ │ │ │ │ +| return ret; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // did we receive this piece from a single peer? | │ │ │ │ │ -| // if we know exactly which blocks failed the hash, we can also be certain | │ │ │ │ │ -| // that all peers in the list sent us bad data | │ │ │ │ │ -| bool const known_bad_peer = (!found_on_disk && peers.size() == 1) || !blocks.empty(); | │ │ │ │ │ +|namespace { | │ │ │ │ │ +| template | │ │ │ │ │ +| int get_setting_impl(Pack const& p, int name, int*) | │ │ │ │ │ +| { return p.get_int(name); } | │ │ │ │ │ | | │ │ │ │ │ -| penalize_peers(peers, index, known_bad_peer); | │ │ │ │ │ -| } | │ │ │ │ │ +| template | │ │ │ │ │ +| bool get_setting_impl(Pack const& p, int name, bool*) | │ │ │ │ │ +| { return p.get_bool(name); } | │ │ │ │ │ | | │ │ │ │ │ -| // If m_storage isn't set here, it means we're shutting down | │ │ │ │ │ -| if (m_storage) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _/_/_ _i_t_ _d_o_e_s_n_'_t_ _m_a_k_e_ _m_u_c_h_ _s_e_n_s_e_ _t_o_ _f_a_i_l_ _t_o_ _h_a_s_h_ _a_ _p_i_e_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_7_5_2_5_ _ _ _ _ _ _ _|_c_o_m_e_ _u_p_ _w_i_t_h_ _a_ _b_e_t_t_e_r_ _w_a_y_ _o_f_ _d_o_i_n_g_ _t_h_i_s_,_ _i_n_s_t_e_a_d_ _o_f_ _a_n_ _i_m_m_e_d_i_a_t_e_l_y_ _i_n_v_o_k_e_d_ _l_a_m_b_d_a_ _e_x_p_r_e_s_s_i_o_n_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ccoommee uupp wwiitthh aa bbeetttteerr wwaayy ooff ddooiinngg tthhiiss,, iinnsstteeaadd ooff aann iimmmmeeddiiaatteellyy iinnvvookkeedd llaammbbddaa eexxpprreessssiioonn.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::77552255 ****** | │ │ │ │ │ -||| peerinfo->confirmed_supports_utp)) | │ │ │ │ │ -| { | │ │ │ │ │ -| sm = m_ses.utp_socket_manager(); | │ │ │ │ │ -| } | │ │ │ │ │ +| template | │ │ │ │ │ +| std::string get_setting_impl(Pack const& p, int name, std::string*) | │ │ │ │ │ +|_ _{_ _r_e_t_u_r_n_ _p_._g_e_t___s_t_r_(_n_a_m_e_)_;_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_1_9_9_8 |could this function be merged with expand_unspecified_addresses? right now both listen_endpoint_t and listen_interface_t are almost | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_i_d_e_n_t_i_c_a_l_,_ _m_a_y_b_e_ _t_h_e_ _l_a_t_t_e_r_ _c_o_u_l_d_ _b_e_ _r_e_m_o_v_e_d_ _t_o_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ccoouulldd tthhiiss ffuunnccttiioonn bbee mmeerrggeedd wwiitthh eexxppaanndd__uunnssppeecciiffiieedd__aaddddrreesssseess?? rriigghhtt nnooww bbootthh lliisstteenn__eennddppooiinntt__tt aanndd lliisstteenn__iinntteerrffaaccee__tt aarree aallmmoosstt iiddeennttiiccaall,, mmaayybbee tthhee llaatttteerr ccoouulldd bbee | │ │ │ │ │ +|rreemmoovveedd ttoooo ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::11999988 ****** | │ │ │ │ │ +|session_log("FATAL SESSION ERROR (%s : %d) [%s]" | │ │ │ │ │ +| , ec.category().name(), ec.value(), ec.message().c_str()); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| this->abort(); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // don't make a TCP connection if it's disabled | │ │ │ │ │ -| if (sm == nullptr && !settings().get_bool(settings_pack::enable_outgoing_tcp)) | │ │ │ │ │ -| { | │ │ │ │ │ +| void session_impl::on_ip_change(error_code const& ec) | │ │ │ │ │ +| { | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log()) | │ │ │ │ │ -| { | │ │ │ │ │ -| debug_log("discarding peer \"%s\": TCP connections disabled " | │ │ │ │ │ -| "[ supports-utp: %d ]", peerinfo->to_string().c_str() | │ │ │ │ │ -| , peerinfo->supports_utp); | │ │ │ │ │ -| } | │ │ │ │ │ +| if (!ec) | │ │ │ │ │ +| session_log("received ip change from internal ip_notifier"); | │ │ │ │ │ +| else | │ │ │ │ │ +| session_log("received error on_ip_change: %d, %s", ec.value(), ec.message().c_str()); | │ │ │ │ │ |#endif | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ +| if (ec || m_abort || !m_ip_notifier) return; | │ │ │ │ │ +| m_ip_notifier->async_wait([this] (error_code const& e) | │ │ │ │ │ +| { wrap(&session_impl::on_ip_change, e); }); | │ │ │ │ │ +| reopen_network_sockets({}); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|aux::socket_type s = [&] { | │ │ │ │ │ +|void interface_to_endpoints(listen_interface_t const& iface | │ │ │ │ │ +|, listen_socket_flags_t flags | │ │ │ │ │ +| , span const ifs | │ │ │ │ │ +| , std::vector& eps) | │ │ │ │ │ +| { | │ │ │ │ │ +| flags |= iface.local ? listen_socket_t::local_network : listen_socket_flags_t{}; | │ │ │ │ │ +| transport const ssl = iface.ssl ? transport::ssl : transport::plaintext; | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| if (peerinfo->is_i2p_addr) | │ │ │ │ │ +| // First, check to see if it's an IP address | │ │ │ │ │ +| error_code err; | │ │ │ │ │ +| address const adr = make_address(iface.device.c_str(), err); | │ │ │ │ │ +| if (!err) | │ │ │ │ │ | { | │ │ │ │ │ -| // It's not entirely obvious why this peer connection is not marked as | │ │ │ │ │ -| // one. The main feature of a peer connection is that whether or not we | │ │ │ │ │ -| // proxy it is configurable. When we use i2p, we want to always prox | │ │ │ │ │ -| // everything via i2p. | │ │ │ │ │ -| | │ │ │ │ │ -| aux::proxy_settings proxy; | │ │ │ │ │ -| proxy.hostname = settings().get_str(settings_pack::i2p_hostname); | │ │ │ │ │ -| proxy.port = std::uint16_t(settings().get_int(settings_pack::i2p_port)); | │ │ │ │ │ -| proxy.type = settings_pack::i2p_proxy; | │ │ │ │ │ -| | │ │ │ │ │ -| aux::socket_type ret = instantiate_connection(m_ses.get_context() | │ │ │ │ │ -| , proxy, nullptr, nullptr, false, false); | │ │ │ │ │ -| i2p_stream& str = boost::get(ret); | │ │ │ │ │ -| str.set_local_i2p_endpoint(m_ses.local_i2p_endpoint()); | │ │ │ │ │ -| str.set_destination(static_cast(peerinfo)->dest()); | │ │ │ │ │ -| str.set_command(i2p_stream::cmd_connect); | │ │ │ │ │ -| str.set_session_id(m_ses.i2p_session()); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| eps.emplace_back(adr, iface.port, std::string{}, ssl, flags); | │ │ │ │ │ | } | │ │ │ │ │ | else | │ │ │ │ │ -|#endif | │ │ │ │ │ | { | │ │ │ │ │ -| void* userdata = nullptr; | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| if (is_ssl_torrent()) | │ │ │ │ │ -|_ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_9_1_1_8_ _ _ _ _ _ _ _|_p_e_r_h_a_p_s_ _0_ _s_h_o_u_l_d_ _a_c_t_u_a_l_l_y_ _m_e_a_n_ _0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ppeerrhhaappss 00 sshhoouulldd aaccttuuaallllyy mmeeaann 00 ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::99111188 ****** | │ │ │ │ │ -|// finished torrents may not change their queue positions, as it's set to | │ │ │ │ │ -| // -1 | │ │ │ │ │ -| if ((m_abort || is_finished()) && p != no_pos) return; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT((p == no_pos) == is_finished() | │ │ │ │ │ -| || (!m_auto_managed && p == no_pos) | │ │ │ │ │ -| || (m_abort && p == no_pos) | │ │ │ │ │ -| || (!m_added && p == no_pos)); | │ │ │ │ │ -| if (p == m_sequence_number) return; | │ │ │ │ │ +| flags |= listen_socket_t::was_expanded; | │ │ │ │ │ | | │ │ │ │ │ -| TORRENT_ASSERT(p >= no_pos); | │ │ │ │ │ +| // this is the case where device names a network device. We need to | │ │ │ │ │ +| // enumerate all IPs associated with this device | │ │ │ │ │ +| for (auto const& ipface : ifs) | │ │ │ │ │ +| { | │ │ │ │ │ +| // we're looking for a specific interface, and its address | │ │ │ │ │ +| // (which must be of the same family as the address we're | │ │ │ │ │ +| // connecting to) | │ │ │ │ │ +| if (iface.device != ipface.name) continue; | │ │ │ │ │ | | │ │ │ │ │ -| state_updated(); | │ │ │ │ │ +| bool const local = iface.local | │ │ │ │ │ +| || ipface.interface_address.is_loopback() | │ │ │ │ │ +|_ _ _ _ _ _|_|_ _i_s___l_i_n_k___l_o_c_a_l_(_i_p_f_a_c_e_._i_n_t_e_r_f_a_c_e___a_d_d_r_e_s_s_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| | |it would probably be better to do this by having a listen-socket "version" number that gets bumped. And instead of setting a bool to| │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_2_3_0_6 |disable a tracker, we set the version number that it was disabled at. This change would affect the ABI in 1.2, so should be done in | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_2_._0_ _o_r_ _l_a_t_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd pprroobbaabbllyy bbee bbeetttteerr ttoo ddoo tthhiiss bbyy hhaavviinngg aa lliisstteenn--ssoocckkeett ""vveerrssiioonn"" nnuummbbeerr tthhaatt ggeettss bbuummppeedd.. AAnndd iinnsstteeaadd ooff sseettttiinngg aa bbooooll ttoo ddiissaabbllee aa ttrraacckkeerr,, wwee sseett tthhee | │ │ │ │ │ +|vveerrssiioonn nnuummbbeerr tthhaatt iitt wwaass ddiissaabblleedd aatt.. TThhiiss cchhaannggee wwoouulldd aaffffeecctt tthhee AABBII iinn 11..22,, ssoo sshhoouulldd bbee ddoonnee iinn 22..00 oorr llaatteerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::22330066 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| for (auto const& s : m_listen_sockets) | │ │ │ │ │ +| remap_ports(remap_natpmp_and_upnp, *s); | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| // new sockets need to map ports even if the caller did not request | │ │ │ │ │ +| // re-mapping | │ │ │ │ │ +| for (auto const& s : new_sockets) | │ │ │ │ │ +| remap_ports(remap_natpmp_and_upnp, *s); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| m_ses.set_queue_position(this, p); | │ │ │ │ │ -| } | │ │ │ │ │ +| update_lsd(); | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::set_max_uploads(int limit, bool const state_update) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -|if (limit <= 0) limit = (1 << 24) - 1; | │ │ │ │ │ -|if (int(m_max_uploads) == limit) return; | │ │ │ │ │ -| if (state_update) state_updated(); | │ │ │ │ │ -| m_max_uploads = aux::numeric_cast(limit); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log() && state_update) | │ │ │ │ │ -| debug_log("*** set-max-uploads: %d", m_max_uploads); | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| open_new_incoming_i2p_connection(); | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| if (state_update) | │ │ │ │ │ -| set_need_save_resume(torrent_handle::if_config_changed); | │ │ │ │ │ +| // trackers that were not reachable, may have become reachable now. | │ │ │ │ │ +| // so clear the "disabled" flags to let them be tried one more time | │ │ │ │ │ +|for (auto& t : m_torrents) | │ │ │ │ │ +|t->enable_all_trackers(); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::set_max_connections(int limit, bool const state_update) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T_(_i_s___s_i_n_g_l_e___t_h_r_e_a_d_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_9_1_3_5_ _ _ _ _ _ _ _|_p_e_r_h_a_p_s_ _0_ _s_h_o_u_l_d_ _a_c_t_u_a_l_l_y_ _m_e_a_n_ _0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ppeerrhhaappss 00 sshhoouulldd aaccttuuaallllyy mmeeaann 00 ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::99113355 ****** | │ │ │ │ │ -| void torrent::set_max_uploads(int limit, bool const state_update) | │ │ │ │ │ +| void session_impl::reopen_network_sockets(reopen_network_flags_t const options) | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| if (limit <= 0) limit = (1 << 24) - 1; | │ │ │ │ │ -| if (int(m_max_uploads) == limit) return; | │ │ │ │ │ -| if (state_update) state_updated(); | │ │ │ │ │ -| m_max_uploads = aux::numeric_cast(limit); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log() && state_update) | │ │ │ │ │ -| debug_log("*** set-max-uploads: %d", m_max_uploads); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (state_update) | │ │ │ │ │ -| set_need_save_resume(torrent_handle::if_config_changed); | │ │ │ │ │ +| reopen_listen_sockets(bool(options & session_handle::reopen_map_ports)); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::set_max_connections(int limit, bool const state_update) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -|if (limit <= 0) limit = (1 << 24) - 1; | │ │ │ │ │ -|if (int(m_max_connections) == limit) return; | │ │ │ │ │ -| if (state_update) state_updated(); | │ │ │ │ │ -| m_max_connections = aux::numeric_cast(limit); | │ │ │ │ │ -| update_want_peers(); | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| if (should_log() && state_update) | │ │ │ │ │ -| debug_log("*** set-max-connections: %d", m_max_connections); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (num_peers() > int(m_max_connections)) | │ │ │ │ │ +| namespace { | │ │ │ │ │ +| template | │ │ │ │ │ +| void map_port(MapProtocol& m, ProtoType protocol, EndpointType const& ep | │ │ │ │ │ +| , port_mapping_t& map_handle, std::string const& device) | │ │ │ │ │ | { | │ │ │ │ │ -| disconnect_peers(num_peers() - m_max_connections | │ │ │ │ │ -| , errors::too_many_connections); | │ │ │ │ │ -| } | │ │ │ │ │ +| if (map_handle != port_mapping_t{-1}) m.delete_mapping(map_handle); | │ │ │ │ │ +| map_handle = port_mapping_t{-1}; | │ │ │ │ │ | | │ │ │ │ │ -| if (state_update) | │ │ │ │ │ -| set_need_save_resume(torrent_handle::if_config_changed); | │ │ │ │ │ -| } | │ │ │ │ │ +| address const addr = ep.address(); | │ │ │ │ │ +| // with IPv4 the interface might be behind NAT so we can't skip them | │ │ │ │ │ +| // based on the scope of the local address | │ │ │ │ │ +| if (addr.is_v6() && is_local(addr)) | │ │ │ │ │ +| return; | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::set_upload_limit(int const limit) | │ │ │ │ │ -| { | │ │ │ │ │ -| set_limit_impl(limit, peer_connection::upload_channel); | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| debug_log("*** set-upload-limit: %d", limit); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // only update this mapping if we actually have a socket listening | │ │ │ │ │ +| if (ep != EndpointType()) | │ │ │ │ │ +| map_handle = m.add_mapping(protocol, ep.port(), ep, device); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void torrent::set_download_limit(int const limit) | │ │ │ │ │ -|_ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t_._c_p_p_:_1_1_0_6_1_ _ _ _ _ _ _|_i_n_s_t_e_a_d_ _o_f_ _r_e_s_o_r_t_i_n_g_ _t_h_e_ _w_h_o_l_e_ _l_i_s_t_,_ _i_n_s_e_r_t_ _t_h_e_ _p_e_e_r_s_ _d_i_r_e_c_t_l_y_ _i_n_t_o_ _t_h_e_ _r_i_g_h_t_ _p_l_a_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinnsstteeaadd ooff rreessoorrttiinngg tthhee wwhhoollee lliisstt,, iinnsseerrtt tthhee ppeeeerrss ddiirreeccttllyy iinnttoo tthhee rriigghhtt ppllaaccee ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt..ccpppp::1111006611 ****** | │ │ │ │ │ -|std::printf("timed out [average-piece-time: %d ms ]\n" | │ │ │ │ │ -| , m_average_piece_time); | │ │ │ │ │ -|#endif | │ │ │ │ │ +| void session_impl::remap_ports(remap_port_mask_t const mask | │ │ │ │ │ +|_ _ _,_ _l_i_s_t_e_n___s_o_c_k_e_t___t_&_ _s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_2_8_6_6_ _ _|_t_h_i_s_ _s_i_z_e_ _n_e_e_d_ _t_o_ _b_e_ _c_a_p_p_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ssiizzee nneeeedd ttoo bbee ccaappppeedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::22886666 ****** | │ │ │ │ │ +|// handshaking | │ │ │ │ │ +| return socket_type(ssl_stream(tcp::socket(std::move(s)), m_peer_ssl_ctx)); | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -| // pick all blocks for this piece. the peers list is kept up to date | │ │ │ │ │ -| // and sorted. when we issue a request to a peer, its download queue | │ │ │ │ │ -| // time will increase and it may need to be bumped in the peers list, | │ │ │ │ │ -| // since it's ordered by download queue time | │ │ │ │ │ -| pick_time_critical_block(peers, ignore_peers | │ │ │ │ │ -| , peers_with_requests | │ │ │ │ │ -| , pi, &i, m_picker.get() | │ │ │ │ │ -| , blocks_in_piece, timed_out); | │ │ │ │ │ -| | │ │ │ │ │ -| // put back the peers we ignored into the peer list for the next piece | │ │ │ │ │ -| if (!ignore_peers.empty()) | │ │ │ │ │ +| else | │ │ │ │ │ +|#endif | │ │ │ │ │ | { | │ │ │ │ │ -| peers.insert(peers.begin(), ignore_peers.begin(), ignore_peers.end()); | │ │ │ │ │ -| ignore_peers.clear(); | │ │ │ │ │ -| | │ │ │ │ │ -|std::sort(peers.begin(), peers.end() | │ │ │ │ │ -|, [] (peer_connection const* lhs, peer_connection const* rhs) | │ │ │ │ │ -| { return lhs->download_queue_time(16*1024) < rhs->download_queue_time(16*1024); }); | │ │ │ │ │ +| return socket_type(tcp::socket(std::move(s))); | │ │ │ │ │ | } | │ │ │ │ │ +| }(); | │ │ │ │ │ | | │ │ │ │ │ -| // if this peer's download time exceeds 2 seconds, we're done. | │ │ │ │ │ -| // We don't want to build unreasonably long request queues | │ │ │ │ │ -| if (!peers.empty() && peers[0]->download_queue_time() > milliseconds(2000)) | │ │ │ │ │ -| break; | │ │ │ │ │ -| } | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| TORRENT_ASSERT((ssl == transport::ssl) == is_ssl(c)); | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| // commit all the time critical requests | │ │ │ │ │ -| for (auto p : peers_with_requests) | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| if (ssl == transport::ssl) | │ │ │ │ │ | { | │ │ │ │ │ -| p->send_block_requests(); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif // TORRENT_DISABLE_STREAMING | │ │ │ │ │ +| TORRENT_ASSERT(is_ssl(c)); | │ │ │ │ │ | | │ │ │ │ │ -| std::set torrent::web_seeds(web_seed_entry::type_t const type) const | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ -| std::set ret; | │ │ │ │ │ -| for (auto const& s : m_web_seeds) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (s.peer_info.banned) continue; | │ │ │ │ │ -| if (s.removed) continue; | │ │ │ │ │ -| if (s.type != type) continue; | │ │ │ │ │ -| ret.insert(s.url); | │ │ │ │ │ +| // save the socket so we can cancel the handshake | │ │ │ │ │ +|auto iter = m_incoming_sockets.emplace(std::make_unique(std::move(c))).first; | │ │ │ │ │ +| | │ │ │ │ │ +| auto sock = iter->get(); | │ │ │ │ │ +| // for SSL connections, incoming_connection() is called | │ │ │ │ │ +| // after the handshake is done | │ │ │ │ │ +| ADD_OUTSTANDING_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ +| boost::get>(**iter).async_accept_handshake( | │ │ │ │ │ +| [this, sock] (error_code const& err) { ssl_handshake(err, sock); }); | │ │ │ │ │ | } | │ │ │ │ │ -|_ _ _r_e_t_u_r_n_ _r_e_t_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n_._c_p_p_:_5_4_0_ _ _ _ _ _ _ _ _|_I_n_ _C_+_+_1_7_._ _u_s_e_ _i_f_ _c_o_n_s_t_e_x_p_r_ _i_n_s_t_e_a_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** IInn CC++++1177.. uussee iiff ccoonnsstteexxpprr iinnsstteeaadd ********** | │ │ │ │ │ -|****** ....//ssrrcc//sseessssiioonn..ccpppp::554400 ****** | │ │ │ │ │ -|{} | │ │ │ │ │ -| session_proxy::session_proxy(session_proxy const&) = default; | │ │ │ │ │ -| session_proxy& session_proxy::operator=(session_proxy const&) & = default; | │ │ │ │ │ -| session_proxy::session_proxy(session_proxy&&) noexcept = default; | │ │ │ │ │ -| session_proxy& session_proxy::operator=(session_proxy&&) & noexcept = default; | │ │ │ │ │ -| session_proxy::~session_proxy() | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_thread && m_thread.use_count() == 1) | │ │ │ │ │ -| { | │ │ │ │ │ -|#if defined TORRENT_ASIO_DEBUGGING | │ │ │ │ │ -| wait_for_asio_handlers(); | │ │ │ │ │ +| else | │ │ │ │ │ |#endif | │ │ │ │ │ -| m_thread->join(); | │ │ │ │ │ +| { | │ │ │ │ │ +| incoming_connection(std::move(c)); | │ │ │ │ │ | } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| TORRENT_EXPORT std::unique_ptr default_disk_io_constructor( | │ │ │ │ │ -| io_context& ios, settings_interface const& sett, counters& cnt) | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| | │ │ │ │ │ +| void session_impl::on_incoming_utp_ssl(socket_type s) | │ │ │ │ │ | { | │ │ │ │ │ -|#if TORRENT_HAVE_MMAP || TORRENT_HAVE_MAP_VIEW_OF_FILE | │ │ │ │ │ -|#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" | │ │ │ │ │ -|if (sizeof(void*) == 8) | │ │ │ │ │ -| return mmap_disk_io_constructor(ios, sett, cnt); | │ │ │ │ │ +| TORRENT_ASSERT(is_ssl(s)); | │ │ │ │ │ +| | │ │ │ │ │ +|_ _ _/_/_ _s_a_v_e_ _t_h_e_ _s_o_c_k_e_t_ _s_o_ _w_e_ _c_a_n_ _c_a_n_c_e_l_ _t_h_e_ _h_a_n_d_s_h_a_k_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_2_8_9_1_ _ _|_t_h_i_s_ _s_i_z_e_ _n_e_e_d_ _t_o_ _b_e_ _c_a_p_p_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss ssiizzee nneeeedd ttoo bbee ccaappppeedd ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::22889911 ****** | │ │ │ │ │ +|// after the handshake is done | │ │ │ │ │ +| ADD_OUTSTANDING_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ +| boost::get>(**iter).async_accept_handshake( | │ │ │ │ │ +| [this, sock] (error_code const& err) { ssl_handshake(err, sock); }); | │ │ │ │ │ +| } | │ │ │ │ │ | else | │ │ │ │ │ -| return posix_disk_io_constructor(ios, sett, cnt); | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ -|#else | │ │ │ │ │ -| return posix_disk_io_constructor(ios, sett, cnt); | │ │ │ │ │ |#endif | │ │ │ │ │ +| { | │ │ │ │ │ +| incoming_connection(std::move(c)); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_c_p_u_i_d_._c_p_p_:_1_3_1_ _ _ _ _ _ _ _ _ _ _|_e_n_a_b_l_e_ _w_h_e_n_ _a_a_r_c_h_6_4_ _i_s_ _r_e_a_l_l_y_ _t_e_s_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** eennaabbllee wwhheenn aaaarrcchh6644 iiss rreeaallllyy tteesstteedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//ccppuuiidd..ccpppp::113311 ****** | │ │ │ │ │ -|bool supports_mmx() noexcept | │ │ │ │ │ -| { | │ │ │ │ │ -|#if TORRENT_HAS_SSE | │ │ │ │ │ -| std::uint32_t cpui[4] = {0}; | │ │ │ │ │ -| cpuid(cpui, 1); | │ │ │ │ │ -| return (cpui[2] & (1 << 23)) != 0; | │ │ │ │ │ -|#else | │ │ │ │ │ -| return false; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ | | │ │ │ │ │ -| bool supports_arm_neon() noexcept | │ │ │ │ │ +| void session_impl::on_incoming_utp_ssl(socket_type s) | │ │ │ │ │ | { | │ │ │ │ │ -|#if TORRENT_HAS_ARM_NEON && TORRENT_HAS_AUXV | │ │ │ │ │ -|#if defined __arm__ | │ │ │ │ │ -| //return (getauxval(AT_HWCAP) & HWCAP_NEON); | │ │ │ │ │ -| return (helper_getauxval(16) & (1 << 12)); | │ │ │ │ │ -|#elif defined __aarch64__ | │ │ │ │ │ -| //return (getauxval(AT_HWCAP) & HWCAP_ASIMD); | │ │ │ │ │ -| //return (getauxval(16) & (1 << 1)); | │ │ │ │ │ -|return false; | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#else | │ │ │ │ │ -| return false; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| TORRENT_ASSERT(is_ssl(s)); | │ │ │ │ │ | | │ │ │ │ │ -| bool supports_arm_crc32c() noexcept | │ │ │ │ │ -| { | │ │ │ │ │ -|#if TORRENT_HAS_ARM_CRC32 && TORRENT_HAS_AUXV | │ │ │ │ │ -|#if defined TORRENT_FORCE_ARM_CRC32 | │ │ │ │ │ -| return true; | │ │ │ │ │ -|#elif defined __arm__ | │ │ │ │ │ -| //return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); | │ │ │ │ │ -| return (helper_getauxval(26) & (1 << 4)); | │ │ │ │ │ -|#elif defined __aarch64__ | │ │ │ │ │ -| //return (getauxval(AT_HWCAP) & HWCAP_CRC32); | │ │ │ │ │ -| return (helper_getauxval(16) & (1 << 7)); | │ │ │ │ │ -|#endif | │ │ │ │ │ -|#else | │ │ │ │ │ -| return false; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ +| // save the socket so we can cancel the handshake | │ │ │ │ │ | | │ │ │ │ │ -|} // anonymous namespace | │ │ │ │ │ +|auto iter = m_incoming_sockets.emplace(std::make_unique(std::move(s))).first; | │ │ │ │ │ +|auto sock = iter->get(); | │ │ │ │ │ | | │ │ │ │ │ -| bool const sse42_support = supports_sse42(); | │ │ │ │ │ -| bool const mmx_support = supports_mmx(); | │ │ │ │ │ -| bool const arm_neon_support = supports_arm_neon(); | │ │ │ │ │ -| bool const arm_crc32c_support = supports_arm_crc32c(); | │ │ │ │ │ -|_}_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_c_h_o_k_e_r_._c_p_p_:_2_5_8_ _ _ _ _ _ _ _ _ _|_m_a_k_e_ _c_o_n_f_i_g_u_r_a_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmaakkee ccoonnffiigguurraabbllee ********** | │ │ │ │ │ -|****** ....//ssrrcc//cchhookkeerr..ccpppp::225588 ****** | │ │ │ │ │ -|// first reset the number of unchoke slots, because we'll calculate | │ │ │ │ │ -| // it purely based on the current state of our peers. | │ │ │ │ │ -| upload_slots = 0; | │ │ │ │ │ +| // for SSL connections, incoming_connection() is called | │ │ │ │ │ +| // after the handshake is done | │ │ │ │ │ +| ADD_OUTSTANDING_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ +| boost::get>(**iter).async_accept_handshake( | │ │ │ │ │ +| [this, sock] (error_code const& err) { ssl_handshake(err, sock); }); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| int rate_threshold = sett.get_int(settings_pack::rate_choker_initial_threshold); | │ │ │ │ │ +| // to test SSL connections, one can use this openssl command template: | │ │ │ │ │ +| // | │ │ │ │ │ +| // openssl s_client -cert .pem -key .pem | │ │ │ │ │ +| // -CAfile .pem -debug -connect 127.0.0.1:4433 -tls1 | │ │ │ │ │ +| // -servername | │ │ │ │ │ | | │ │ │ │ │ -| std::sort(peers.begin(), peers.end() | │ │ │ │ │ -| , [](peer_connection const* lhs, peer_connection const* rhs) | │ │ │ │ │ -| { return upload_rate_compare(lhs, rhs); }); | │ │ │ │ │ +| void session_impl::ssl_handshake(error_code const& ec, socket_type* sock) | │ │ │ │ │ +| { | │ │ │ │ │ +| COMPLETE_ASYNC("session_impl::ssl_handshake"); | │ │ │ │ │ | | │ │ │ │ │ -| for (auto const* p : peers) | │ │ │ │ │ -| { | │ │ │ │ │ -| int const rate = int(p->uploaded_in_last_round() | │ │ │ │ │ -| * 1000 / total_milliseconds(unchoke_interval)); | │ │ │ │ │ +| auto iter = m_incoming_sockets.find(sock); | │ │ │ │ │ | | │ │ │ │ │ -| // always have at least 1 unchoke slot | │ │ │ │ │ -| if (rate < rate_threshold) break; | │ │ │ │ │ +| // this happens if the SSL connection is aborted because we're shutting | │ │ │ │ │ +| // down | │ │ │ │ │ +| if (iter == m_incoming_sockets.end()) return; | │ │ │ │ │ | | │ │ │ │ │ -| ++upload_slots; | │ │ │ │ │ +| socket_type s(std::move(**iter)); | │ │ │ │ │ +| TORRENT_ASSERT(is_ssl(s)); | │ │ │ │ │ +| m_incoming_sockets.erase(iter); | │ │ │ │ │ | | │ │ │ │ │ -|rate_threshold += 2048; | │ │ │ │ │ -|} | │ │ │ │ │ -| ++upload_slots; | │ │ │ │ │ +|_ _ _e_r_r_o_r___c_o_d_e_ _e_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_3_5_9_0_ _ _|_h_a_v_e_ _a_ _s_e_p_a_r_a_t_e_ _l_i_s_t_ _f_o_r_ _t_h_e_s_e_ _c_o_n_n_e_c_t_i_o_n_s_,_ _i_n_s_t_e_a_d_ _o_f_ _h_a_v_i_n_g_ _t_o_ _l_o_o_p_ _t_h_r_o_u_g_h_ _a_l_l_ _o_f_ _t_h_e_m_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** hhaavvee aa sseeppaarraattee lliisstt ffoorr tthheessee ccoonnnneeccttiioonnss,, iinnsstteeaadd ooff hhaavviinngg ttoo lloooopp tthhrroouugghh aallll ooff tthheemm ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::33559900 ****** | │ │ │ │ │ +|// -------------------------------------------------------------- | │ │ │ │ │ +| if (!m_paused) m_auto_manage_time_scaler--; | │ │ │ │ │ +| if (m_auto_manage_time_scaler < 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_auto_manage_time_scaler = settings().get_int(settings_pack::auto_manage_interval); | │ │ │ │ │ +| recalculate_auto_managed_torrents(); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // sorts the peers that are eligible for unchoke by download rate and | │ │ │ │ │ -| // secondary by total upload. The reason for this is, if all torrents are | │ │ │ │ │ -| // being seeded, the download rate will be 0, and the peers we have sent | │ │ │ │ │ -| // the least to should be unchoked | │ │ │ │ │ -| | │ │ │ │ │ -| // we use partial sort here, because we only care about the top | │ │ │ │ │ -| // upload_slots peers. | │ │ │ │ │ -| | │ │ │ │ │ -| int const slots = std::min(upload_slots, int(peers.size())); | │ │ │ │ │ +| // -------------------------------------------------------------- | │ │ │ │ │ +| // check for incoming connections that might have timed out | │ │ │ │ │ +| // -------------------------------------------------------------- | │ │ │ │ │ | | │ │ │ │ │ -| if (sett.get_int(settings_pack::seed_choking_algorithm) | │ │ │ │ │ -| == settings_pack::round_robin) | │ │ │ │ │ +| for (auto i = m_connections.begin(); i != m_connections.end();) | │ │ │ │ │ | { | │ │ │ │ │ -| int const pieces = sett.get_int(settings_pack::seeding_piece_quota); | │ │ │ │ │ +| peer_connection* p = (*i).get(); | │ │ │ │ │ +| ++i; | │ │ │ │ │ +| // ignore connections that already have a torrent, since they | │ │ │ │ │ +| // are ticked through the torrents' second_tick | │ │ │ │ │ +| if (!p->associated_torrent().expired()) continue; | │ │ │ │ │ | | │ │ │ │ │ -| std::nth_element(peers.begin(), peers.begin() | │ │ │ │ │ -| + slots, peers.end() | │ │ │ │ │ -| , [pieces](peer_connection const* lhs, peer_connection const* rhs) | │ │ │ │ │ -| { return unchoke_compare_rr(lhs, rhs, pieces); }); | │ │ │ │ │ +|int timeout = m_settings.get_int(settings_pack::handshake_timeout); | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| timeout *= is_i2p(p->get_socket()) ? 4 : 1; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| if (m_last_tick - p->connected_time () > seconds(timeout)) | │ │ │ │ │ +| p->disconnect(errors::timed_out, operation_t::bittorrent); | │ │ │ │ │ | } | │ │ │ │ │ -| else if (sett.get_int(settings_pack::seed_choking_algorithm) | │ │ │ │ │ -| == settings_pack::fastest_upload) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::nth_element(peers.begin(), peers.begin() | │ │ │ │ │ -| + slots, peers.end() | │ │ │ │ │ -|_ _ _ _ _,_ _[_]_(_p_e_e_r___c_o_n_n_e_c_t_i_o_n_ _c_o_n_s_t_*_ _l_h_s_,_ _p_e_e_r___c_o_n_n_e_c_t_i_o_n_ _c_o_n_s_t_*_ _r_h_s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_1_1_0_ _ _ _ _|_i_n_ _C_+_+_2_0_,_ _u_s_e_ _s_t_d_:_:_i_d_e_n_t_i_t_y_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinn CC++++2200,, uussee ssttdd::::iiddeennttiittyy ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::111100 ****** | │ │ │ │ │ -|allocate_full(); | │ │ │ │ │ -| | │ │ │ │ │ -| merkle_validate_copy(t, m_tree, root(), m_block_verified); | │ │ │ │ │ -| | │ │ │ │ │ -| load_verified_bits(verified); | │ │ │ │ │ | | │ │ │ │ │ -| optimize_storage(); | │ │ │ │ │ -| optimize_storage_piece_layer(); | │ │ │ │ │ -| } | │ │ │ │ │ +| // -------------------------------------------------------------- | │ │ │ │ │ +| // second_tick every torrent (that wants it) | │ │ │ │ │ +| // -------------------------------------------------------------- | │ │ │ │ │ | | │ │ │ │ │ -| void merkle_tree::clear() | │ │ │ │ │ -| { | │ │ │ │ │ -| m_tree.clear(); | │ │ │ │ │ -| m_tree.shrink_to_fit(); | │ │ │ │ │ -| m_block_verified.clear(); | │ │ │ │ │ -| m_mode = mode_t::empty_tree; | │ │ │ │ │ -| } | │ │ │ │ │ +|#if TORRENT_DEBUG_STREAMING > 0 | │ │ │ │ │ +| std::printf("\033[2J\033[0;0H"); | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -|namespace { | │ │ │ │ │ +| aux::vector& want_tick = m_torrent_lists[torrent_want_tick]; | │ │ │ │ │ +| for (int i = 0; i < int(want_tick.size()); ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| torrent& t = *want_tick[i]; | │ │ │ │ │ +| TORRENT_ASSERT(t.want_tick()); | │ │ │ │ │ +| TORRENT_ASSERT(!t.is_aborted()); | │ │ │ │ │ | | │ │ │ │ │ -|struct identity | │ │ │ │ │ -|{ | │ │ │ │ │ -| bool operator()(bool b) const { return b; } | │ │ │ │ │ -| }; | │ │ │ │ │ -|} | │ │ │ │ │ +| t.second_tick(tick_interval_ms); | │ │ │ │ │ | | │ │ │ │ │ -| void merkle_tree::load_sparse_tree(span t | │ │ │ │ │ -| , std::vector const& mask | │ │ │ │ │ -| , std::vector const& verified) | │ │ │ │ │ -| { | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| TORRENT_ASSERT(mask.size() == size()); | │ │ │ │ │ -| if (size() != mask.size()) return; | │ │ │ │ │ +| // if the call to second_tick caused the torrent | │ │ │ │ │ +| // to no longer want to be ticked (i.e. it was | │ │ │ │ │ +| // removed from the list) we need to back up the counter | │ │ │ │ │ +| // to not miss the torrent after it | │ │ │ │ │ +| if (!t.want_tick()) --i; | │ │ │ │ │ +|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_3_6_2_3_ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _a_p_p_l_y_ _t_o_ _a_l_l_ _b_a_n_d_w_i_d_t_h_ _c_h_a_n_n_e_l_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss sshhoouulldd aappppllyy ttoo aallll bbaannddwwiiddtthh cchhaannnneellss ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::33662233 ****** | │ │ │ │ │ +|#if TORRENT_DEBUG_STREAMING > 0 | │ │ │ │ │ +| std::printf("\033[2J\033[0;0H"); | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| int const first_block = block_layer_start(); | │ │ │ │ │ -| int const end_block = first_block + m_num_blocks; | │ │ │ │ │ +| aux::vector& want_tick = m_torrent_lists[torrent_want_tick]; | │ │ │ │ │ +| for (int i = 0; i < int(want_tick.size()); ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| torrent& t = *want_tick[i]; | │ │ │ │ │ +| TORRENT_ASSERT(t.want_tick()); | │ │ │ │ │ +| TORRENT_ASSERT(!t.is_aborted()); | │ │ │ │ │ | | │ │ │ │ │ -| TORRENT_ASSERT(first_block < int(mask.size())); | │ │ │ │ │ -| TORRENT_ASSERT(end_block <= int(mask.size())); | │ │ │ │ │ +| t.second_tick(tick_interval_ms); | │ │ │ │ │ | | │ │ │ │ │ -| // if the mask covers all blocks, go straight to block_layer | │ │ │ │ │ -| // mode, and validate | │ │ │ │ │ -| if (std::all_of(mask.begin() + first_block, mask.begin() + end_block, identity())) | │ │ │ │ │ -| { | │ │ │ │ │ -| // the index in t that points to first_block | │ │ │ │ │ -| auto const block_index = std::count_if(mask.begin(), mask.begin() + first_block, identity()); | │ │ │ │ │ +| // if the call to second_tick caused the torrent | │ │ │ │ │ +| // to no longer want to be ticked (i.e. it was | │ │ │ │ │ +| // removed from the list) we need to back up the counter | │ │ │ │ │ +| // to not miss the torrent after it | │ │ │ │ │ +| if (!t.want_tick()) --i; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // discrepancy | │ │ │ │ │ -| if (t.size() < block_index + m_num_blocks) | │ │ │ │ │ -|_ _ _ _ _r_e_t_u_r_n_ _c_l_e_a_r_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_3_1_9_ _ _ _ _|_t_h_i_s_ _c_a_n_ _b_e_ _o_p_t_i_m_i_z_e_d_ _b_y_ _u_s_i_n_g_ _m___t_r_e_e_ _a_s_ _s_t_o_r_a_g_e_ _t_o_ _f_i_l_l_ _t_h_i_s_ _t_r_e_e_ _i_n_t_o_,_ _a_n_d_ _t_h_e_n_ _c_l_e_a_r_ _i_t_ _i_f_ _t_h_e_ _h_a_s_h_e_s_ _f_a_i_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ccaann bbee ooppttiimmiizzeedd bbyy uussiinngg mm__ttrreeee aass ssttoorraaggee ttoo ffiillll tthhiiss ttrreeee iinnttoo,, aanndd tthheenn cclleeaarr iitt iiff tthhee hhaasshheess ffaaiill ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::331199 ****** | │ │ │ │ │ +|if (m_settings.get_bool(settings_pack::rate_limit_ip_overhead)) | │ │ │ │ │ |{ | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ +| int const up_limit = upload_rate_limit(m_global_class); | │ │ │ │ │ +| int const down_limit = download_rate_limit(m_global_class); | │ │ │ │ │ | | │ │ │ │ │ -| // as we set the hashes of interior nodes, we may be able to validate | │ │ │ │ │ -| // block hashes that we had since earlier. Any blocks that can be | │ │ │ │ │ -| // validated, and failed, are added to this list | │ │ │ │ │ -| add_hashes_result_t ret; | │ │ │ │ │ +| if (down_limit > 0 | │ │ │ │ │ +| && m_stat.download_ip_overhead() >= down_limit | │ │ │ │ │ +| && m_alerts.should_post()) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_alerts.emplace_alert(torrent_handle() | │ │ │ │ │ +| , performance_alert::download_limit_too_low); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // we already have all hashes | │ │ │ │ │ -| if (m_mode == mode_t::block_layer) | │ │ │ │ │ -| { | │ │ │ │ │ -| // since we're already on the block layer mode, we have the whole | │ │ │ │ │ -| // tree, and we've already reported any pieces as passing that may | │ │ │ │ │ -| // have existed in the tree when we completed it. At this point no | │ │ │ │ │ -| // more pieces should be reported as passed | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| if (up_limit > 0 | │ │ │ │ │ +| && m_stat.upload_ip_overhead() >= up_limit | │ │ │ │ │ +| && m_alerts.should_post()) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_alerts.emplace_alert(torrent_handle() | │ │ │ │ │ +| , performance_alert::upload_limit_too_low); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| allocate_full(); | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| m_peak_up_rate = std::max(m_stat.upload_rate(), m_peak_up_rate); | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -|int const leaf_count = merkle_num_leafs(int(hashes.size())); | │ │ │ │ │ -|aux::vector tree(merkle_num_nodes(leaf_count)); | │ │ │ │ │ -| std::copy(hashes.begin(), hashes.end(), tree.end() - leaf_count); | │ │ │ │ │ +| m_stat.second_tick(tick_interval_ms); | │ │ │ │ │ | | │ │ │ │ │ -| // the end of a file is a special case, we may need to pad the leaf layer | │ │ │ │ │ -| if (leaf_count > hashes.size()) | │ │ │ │ │ +| // -------------------------------------------------------------- | │ │ │ │ │ +| // scrape paused torrents that are auto managed | │ │ │ │ │ +|_ _ _/_/_ _(_u_n_l_e_s_s_ _t_h_e_ _s_e_s_s_i_o_n_ _i_s_ _p_a_u_s_e_d_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_4_3_1_4 |use a lower limit than m_settings.connections_limit to allocate the to 10% or so of connection slots for incoming connections cap | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_h_i_s_ _a_t_ _m_a_x_ _-_ _1_,_ _s_i_n_c_e_ _w_e_ _m_a_y_ _a_d_d_ _o_n_e_ _b_e_l_o_w_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee aa lloowweerr lliimmiitt tthhaann mm__sseettttiinnggss..ccoonnnneeccttiioonnss__lliimmiitt ttoo aallllooccaattee tthhee ttoo 1100%% oorr ssoo ooff ccoonnnneeccttiioonn sslloottss ffoorr iinnccoommiinngg ccoonnnneeccttiioonnss ccaapp tthhiiss aatt mmaaxx -- 11,, ssiinnccee wwee mmaayy aadddd oonnee | │ │ │ │ │ +|bbeellooww ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::44331144 ****** | │ │ │ │ │ +|// boost, which are done immediately on a tracker response. These | │ │ │ │ │ +| // connections needs to be deducted from the regular connection attempt | │ │ │ │ │ +| // quota for this tick | │ │ │ │ │ +| if (m_boost_connections > 0) | │ │ │ │ │ | { | │ │ │ │ │ -| int const leaf_layer_size = num_leafs(); | │ │ │ │ │ -| // assuming uncle_hashes lead all the way to the root, they tell us | │ │ │ │ │ -| // how many layers down we are | │ │ │ │ │ -| int const insert_layer_size = leaf_count << uncle_hashes.size(); | │ │ │ │ │ -| if (leaf_layer_size != insert_layer_size) | │ │ │ │ │ +| if (m_boost_connections > max_connections) | │ │ │ │ │ | { | │ │ │ │ │ -| sha256_hash const pad_hash = merkle_pad(leaf_layer_size, insert_layer_size); | │ │ │ │ │ -| for (int i = int(hashes.size()); i < leaf_count; ++i) | │ │ │ │ │ -| tree[tree.end_index() - leaf_count + i] = pad_hash; | │ │ │ │ │ +| m_boost_connections -= max_connections; | │ │ │ │ │ +| max_connections = 0; | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| max_connections -= m_boost_connections; | │ │ │ │ │ +| m_boost_connections = 0; | │ │ │ │ │ | } | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| merkle_fill_tree(tree, leaf_count); | │ │ │ │ │ -| | │ │ │ │ │ -| int const base_num_layers = merkle_num_layers(leaf_count); | │ │ │ │ │ -| | │ │ │ │ │ -| // this is the index of the node where we'll insert the root of the | │ │ │ │ │ -| // subtree (tree). It's also the hash the uncle_hashes are here to prove | │ │ │ │ │ -| // is valid. | │ │ │ │ │ -| int const insert_root_idx = dest_start_idx >> base_num_layers; | │ │ │ │ │ -| | │ │ │ │ │ -| // start with validating the proofs, and inserting them as we go. | │ │ │ │ │ -| if (!merkle_validate_and_insert_proofs(m_tree, insert_root_idx, tree[0], uncle_hashes)) | │ │ │ │ │ -|_ _ _ _r_e_t_u_r_n_ _{_}_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_3_6_7_ _ _ _ _|_a_ _p_i_e_c_e_ _o_u_t_s_i_d_e_ _o_f_ _t_h_i_s_ _r_a_n_g_e_ _m_a_y_ _a_l_s_o_ _f_a_i_l_,_ _i_f_ _o_n_e_ _o_f_ _t_h_e_ _u_n_c_l_e_ _h_a_s_h_e_s_ _i_s_ _a_t_ _t_h_e_ _l_a_y_e_r_ _r_i_g_h_t_ _a_b_o_v_e_ _t_h_e_ _b_l_o_c_k_ _h_a_s_h_e_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aa ppiieeccee oouuttssiiddee ooff tthhiiss rraannggee mmaayy aallssoo ffaaiill,, iiff oonnee ooff tthhee uunnccllee hhaasshheess iiss aatt tthhee llaayyeerr rriigghhtt aabboovvee tthhee bblloocckk hhaasshheess ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::336677 ****** | │ │ │ │ │ -|int const insert_root_idx = dest_start_idx >> base_num_layers; | │ │ │ │ │ -| | │ │ │ │ │ -| // start with validating the proofs, and inserting them as we go. | │ │ │ │ │ -| if (!merkle_validate_and_insert_proofs(m_tree, insert_root_idx, tree[0], uncle_hashes)) | │ │ │ │ │ -| return {}; | │ │ │ │ │ -| | │ │ │ │ │ -| // first fill in the subtree of known hashes from the base layer | │ │ │ │ │ -| auto const num_leafs = merkle_num_leafs(m_num_blocks); | │ │ │ │ │ -| auto const first_leaf = merkle_first_leaf(num_leafs); | │ │ │ │ │ +| // zero connections speeds are allowed, we just won't make any connections | │ │ │ │ │ +| if (max_connections <= 0) return; | │ │ │ │ │ | | │ │ │ │ │ -| // this is the start of the leaf layer of "tree". We'll use this | │ │ │ │ │ -| // variable to step upwards towards the root | │ │ │ │ │ -| int source_cursor = int(tree.size()) - leaf_count; | │ │ │ │ │ -| // the running index in the loop | │ │ │ │ │ -| int dest_cursor = dest_start_idx; | │ │ │ │ │ +|int const limit = std::min(m_settings.get_int(settings_pack::connections_limit) | │ │ │ │ │ +|- num_connections(), std::numeric_limits::max() - 1); | │ │ │ │ │ | | │ │ │ │ │ -| // the number of tree levels in a piece hash. 0 means the block layer is | │ │ │ │ │ -| // the same as the piece layer | │ │ │ │ │ -| int const base = piece_levels(); | │ │ │ │ │ +| // this logic is here to smooth out the number of new connection | │ │ │ │ │ +| // attempts over time, to prevent connecting a large number of | │ │ │ │ │ +| // sockets, wait 10 seconds, and then try again | │ │ │ │ │ +| if (m_settings.get_bool(settings_pack::smooth_connects) && max_connections > (limit+1) / 2) | │ │ │ │ │ +| max_connections = (limit + 1) / 2; | │ │ │ │ │ | | │ │ │ │ │ -|for (int layer_size = leaf_count; layer_size != 0; layer_size /= 2) | │ │ │ │ │ -|{ | │ │ │ │ │ -| for (int i = 0; i < layer_size; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| int const dst_idx = dest_cursor + i; | │ │ │ │ │ -| int const src_idx = source_cursor + i; | │ │ │ │ │ -| if (has_node(dst_idx)) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_tree[dst_idx] != tree[src_idx]) | │ │ │ │ │ -| { | │ │ │ │ │ -| // this must be a block hash because inner nodes are not filled in until | │ │ │ │ │ -| // they can be verified. This assert ensures we're at the | │ │ │ │ │ -| // leaf layer of the file tree | │ │ │ │ │ -| TORRENT_ASSERT(dst_idx >= first_leaf); | │ │ │ │ │ +| aux::vector& want_peers_download = m_torrent_lists[torrent_want_peers_download]; | │ │ │ │ │ +| aux::vector& want_peers_finished = m_torrent_lists[torrent_want_peers_finished]; | │ │ │ │ │ | | │ │ │ │ │ -| int const pos = dst_idx - first_leaf; | │ │ │ │ │ -| auto const piece = piece_index_t{pos >> m_blocks_per_piece_log} + file_piece_offset; | │ │ │ │ │ -| int const block = pos & ((1 << m_blocks_per_piece_log) - 1); | │ │ │ │ │ +| // if no torrent want any peers, just return | │ │ │ │ │ +| if (want_peers_download.empty() && want_peers_finished.empty()) return; | │ │ │ │ │ | | │ │ │ │ │ -| TORRENT_ASSERT(pos < m_num_blocks); | │ │ │ │ │ -| if (!ret.failed.empty() && ret.failed.back().first == piece) | │ │ │ │ │ -| ret.failed.back().second.push_back(block); | │ │ │ │ │ -| else | │ │ │ │ │ -| ret.failed.emplace_back(piece, std::vector{block}); | │ │ │ │ │ +| // if we don't have any connection attempt quota, return | │ │ │ │ │ +| if (max_connections <= 0) return; | │ │ │ │ │ | | │ │ │ │ │ -| // now that this hash has been reported as failing, we | │ │ │ │ │ -| // can clear it. This will prevent it from being | │ │ │ │ │ -| // reported as failing again. | │ │ │ │ │ -| m_tree[dst_idx].clear(); | │ │ │ │ │ -| } | │ │ │ │ │ -|_ _ _ _ _ _e_l_s_e_ _i_f_ _(_d_s_t___i_d_x_ _>_=_ _f_i_r_s_t___l_e_a_f_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_4_4_7 |instead of overwriting the root and comparing it against hashes[], write a functions that *validates* a tree by just filling it up | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_o_ _t_h_e_ _l_e_v_e_l_ _b_e_l_o_w_ _t_h_e_ _r_o_o_t_ _a_n_d_ _t_h_e_n_ _v_a_l_i_d_a_t_e_s_ _i_t_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinnsstteeaadd ooff oovveerrwwrriittiinngg tthhee rroooott aanndd ccoommppaarriinngg iitt aaggaaiinnsstt hhaasshheess[[]],, wwrriittee aa ffuunnccttiioonnss tthhaatt **vvaalliiddaatteess** aa ttrreeee bbyy jjuusstt ffiilllliinngg iitt uupp ttoo tthhee lleevveell bbeellooww tthhee rroooott aanndd tthheenn | │ │ │ │ │ -|vvaalliiddaatteess iitt.. ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::444477 ****** | │ │ │ │ │ -|&& dest_start_idx < first_piece_idx + num_pieces()) | │ │ │ │ │ +| int steps_since_last_connect = 0; | │ │ │ │ │ +| int const num_torrents = int(want_peers_finished.size() + want_peers_download.size()); | │ │ │ │ │ +| for (;;) | │ │ │ │ │ | { | │ │ │ │ │ -| int const blocks_in_piece = 1 << base; | │ │ │ │ │ -| | │ │ │ │ │ -| // it may now be possible to verify the hashes of previously received blocks | │ │ │ │ │ -| // try to verify as many child nodes of the received hashes as possible | │ │ │ │ │ -| for (int i = 0; i < int(hashes.size()); ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| int const piece = dest_start_idx + i; | │ │ │ │ │ -| if (piece - first_piece_idx >= num_pieces()) | │ │ │ │ │ -| break; | │ │ │ │ │ -| // the first block in this piece | │ │ │ │ │ -| int const block_idx = merkle_get_first_child(piece, base); | │ │ │ │ │ +| if (m_next_downloading_connect_torrent >= int(want_peers_download.size())) | │ │ │ │ │ +| m_next_downloading_connect_torrent = 0; | │ │ │ │ │ | | │ │ │ │ │ -| int const block_end_idx = std::min(block_idx + blocks_in_piece, first_leaf + m_num_blocks); | │ │ │ │ │ -| if (std::any_of(m_tree.begin() + block_idx | │ │ │ │ │ -| , m_tree.begin() + block_end_idx | │ │ │ │ │ -| , [](sha256_hash const& h) { return h.is_all_zeros(); })) | │ │ │ │ │ -| continue; | │ │ │ │ │ +| if (m_next_finished_connect_torrent >= int(want_peers_finished.size())) | │ │ │ │ │ +| m_next_finished_connect_torrent = 0; | │ │ │ │ │ | | │ │ │ │ │ -|merkle_fill_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ -|if (m_tree[piece] != hashes[i]) | │ │ │ │ │ -| { | │ │ │ │ │ -| merkle_clear_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ -| // write back the correct hash | │ │ │ │ │ -| m_tree[piece] = hashes[i]; | │ │ │ │ │ -| TORRENT_ASSERT(blocks_in_piece == blocks_per_piece()); | │ │ │ │ │ +| torrent* t = nullptr; | │ │ │ │ │ +| // there are prioritized torrents. Pick one of those | │ │ │ │ │ +|_ _ _ _w_h_i_l_e_ _(_!_m___p_r_i_o___t_o_r_r_e_n_t_s_._e_m_p_t_y_(_)_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_4_4_5_9_ _ _|_p_o_s_t_ _a_ _m_e_s_s_a_g_e_ _t_o_ _h_a_v_e_ _t_h_i_s_ _h_a_p_p_e_n_ _i_m_m_e_d_i_a_t_e_l_y_ _i_n_s_t_e_a_d_ _o_f_ _w_a_i_t_i_n_g_ _f_o_r_ _t_h_e_ _n_e_x_t_ _t_i_c_k_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ppoosstt aa mmeessssaaggee ttoo hhaavvee tthhiiss hhaappppeenn iimmmmeeddiiaatteellyy iinnsstteeaadd ooff wwaaiittiinngg ffoorr tthhee nneexxtt ttiicckk ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::44445599 ****** | │ │ │ │ │ +|continue; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // an empty blocks vector indicates that we don't have the | │ │ │ │ │ -| // block hashes, and we can't know which block failed | │ │ │ │ │ -| // this will cause the block hashes to be requested | │ │ │ │ │ -| ret.failed.emplace_back(piece_index_t{piece - first_piece_idx} + file_piece_offset | │ │ │ │ │ -| , std::vector()); | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| ret.passed.push_back(piece_index_t{piece - first_piece_idx} + file_piece_offset); | │ │ │ │ │ -| // record that these block hashes are correct! | │ │ │ │ │ -| int const leafs_start = block_idx - block_layer_start(); | │ │ │ │ │ -|_ _ _ _ _ _i_n_t_ _c_o_n_s_t_ _l_e_a_f_s___e_n_d_ _=_ _s_t_d_:_:_m_i_n_(_m___n_u_m___b_l_o_c_k_s_,_ _l_e_a_f_s___s_t_a_r_t_ _+_ _b_l_o_c_k_s___i_n___p_i_e_c_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_4_7_1_ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _d_o_n_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_l_y_ _i_f_ _b_i_t_f_i_e_l_d_ _h_a_d_ _a_ _f_u_n_c_t_i_o_n_ _t_o_ _s_e_t_ _a_ _r_a_n_g_e_ _o_f_ _b_i_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ccoouulldd bbee ddoonnee mmoorree eeffffiicciieennttllyy iiff bbiittffiieelldd hhaadd aa ffuunnccttiioonn ttoo sseett aa rraannggee ooff bbiittss ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::447711 ****** | │ │ │ │ │ -|merkle_fill_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ -| if (m_tree[piece] != hashes[i]) | │ │ │ │ │ +| if (!p->is_peer_interested() | │ │ │ │ │ +| || p->is_disconnecting() | │ │ │ │ │ +| || p->is_connecting()) | │ │ │ │ │ +| { | │ │ │ │ │ +| // this peer is not unchokable. So, if it's unchoked | │ │ │ │ │ +| // already, make sure to choke it. | │ │ │ │ │ +| if (p->is_choked()) | │ │ │ │ │ | { | │ │ │ │ │ -| merkle_clear_tree(m_tree, blocks_in_piece, block_idx); | │ │ │ │ │ -| // write back the correct hash | │ │ │ │ │ -| m_tree[piece] = hashes[i]; | │ │ │ │ │ -| TORRENT_ASSERT(blocks_in_piece == blocks_per_piece()); | │ │ │ │ │ -| | │ │ │ │ │ -| // an empty blocks vector indicates that we don't have the | │ │ │ │ │ -| // block hashes, and we can't know which block failed | │ │ │ │ │ -| // this will cause the block hashes to be requested | │ │ │ │ │ -| ret.failed.emplace_back(piece_index_t{piece - first_piece_idx} + file_piece_offset | │ │ │ │ │ -| , std::vector()); | │ │ │ │ │ +| p->reset_choke_counters(); | │ │ │ │ │ +| continue; | │ │ │ │ │ | } | │ │ │ │ │ -| else | │ │ │ │ │ +| if (pi && pi->optimistically_unchoked) | │ │ │ │ │ | { | │ │ │ │ │ -| ret.passed.push_back(piece_index_t{piece - first_piece_idx} + file_piece_offset); | │ │ │ │ │ -| // record that these block hashes are correct! | │ │ │ │ │ -| int const leafs_start = block_idx - block_layer_start(); | │ │ │ │ │ -| int const leafs_end = std::min(m_num_blocks, leafs_start + blocks_in_piece); | │ │ │ │ │ -|for (int k = leafs_start; k < leafs_end; ++k) | │ │ │ │ │ -|m_block_verified.set_bit(k); | │ │ │ │ │ -| } | │ │ │ │ │ -| TORRENT_ASSERT((piece - first_piece_idx) >= 0); | │ │ │ │ │ +| m_stats_counters.inc_stats_counter(counters::num_peers_up_unchoked_optimistic, -1); | │ │ │ │ │ +| pi->optimistically_unchoked = false; | │ │ │ │ │ +| // force a new optimistic unchoke | │ │ │ │ │ +| m_optimistic_unchoke_time_scaler = 0; | │ │ │ │ │ +|} | │ │ │ │ │ +|t->choke_peer(*p); | │ │ │ │ │ +| p->reset_choke_counters(); | │ │ │ │ │ +| continue; | │ │ │ │ │ | } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| optimize_storage(); | │ │ │ │ │ -| | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| std::tuple merkle_tree::set_block(int const block_index | │ │ │ │ │ -| , sha256_hash const& h) | │ │ │ │ │ -| { | │ │ │ │ │ -|#ifdef TORRENT_EXPENSIVE_INVARIANT_CHECKS | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| TORRENT_ASSERT(block_index < m_num_blocks); | │ │ │ │ │ | | │ │ │ │ │ -| auto const num_leafs = merkle_num_leafs(m_num_blocks); | │ │ │ │ │ -| auto const first_leaf = merkle_first_leaf(num_leafs); | │ │ │ │ │ -| auto const block_tree_index = first_leaf + block_index; | │ │ │ │ │ +| peers.push_back(p.get()); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (blocks_verified(block_index, 1)) | │ │ │ │ │ -| { | │ │ │ │ │ -| // if this blocks's hash is already known, check the passed-in hash against it | │ │ │ │ │ -| if (compare_node(block_tree_index, h)) | │ │ │ │ │ -| return std::make_tuple(set_block_result::ok, block_index, 1); | │ │ │ │ │ -| else | │ │ │ │ │ -|_ _ _ _ _r_e_t_u_r_n_ _s_t_d_:_:_m_a_k_e___t_u_p_l_e_(_s_e_t___b_l_o_c_k___r_e_s_u_l_t_:_:_b_l_o_c_k___h_a_s_h___f_a_i_l_e_d_,_ _b_l_o_c_k___i_n_d_e_x_,_ _1_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_5_1_4_ _ _ _ _|_u_s_e_ _s_t_r_u_c_t_u_r_e_d_ _b_i_n_d_i_n_g_ _i_n_ _C_+_+_1_7_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** uussee ssttrruuccttuurreedd bbiinnddiinngg iinn CC++++1177 ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::551144 ****** | │ │ │ │ │ -|auto const first_leaf = merkle_first_leaf(num_leafs); | │ │ │ │ │ -| auto const block_tree_index = first_leaf + block_index; | │ │ │ │ │ +| int const allowed_upload_slots = unchoke_sort(peers | │ │ │ │ │ +| , unchoke_interval, m_settings); | │ │ │ │ │ | | │ │ │ │ │ -| if (blocks_verified(block_index, 1)) | │ │ │ │ │ +| if (m_settings.get_int(settings_pack::choking_algorithm) == settings_pack::fixed_slots_choker) | │ │ │ │ │ | { | │ │ │ │ │ -| // if this blocks's hash is already known, check the passed-in hash against it | │ │ │ │ │ -| if (compare_node(block_tree_index, h)) | │ │ │ │ │ -| return std::make_tuple(set_block_result::ok, block_index, 1); | │ │ │ │ │ -| else | │ │ │ │ │ -| return std::make_tuple(set_block_result::block_hash_failed, block_index, 1); | │ │ │ │ │ +| int const upload_slots = get_int_setting(settings_pack::unchoke_slots_limit); | │ │ │ │ │ +| m_stats_counters.set_value(counters::num_unchoke_slots, upload_slots); | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -| allocate_full(); | │ │ │ │ │ -| | │ │ │ │ │ -| m_tree[block_tree_index] = h; | │ │ │ │ │ -| | │ │ │ │ │ -| // to avoid wasting a lot of time hashing nodes only to discover they | │ │ │ │ │ -| // cannot be verified, check first to see if the root of the largest | │ │ │ │ │ -| // computable subtree is known | │ │ │ │ │ -| | │ │ │ │ │ -|int leafs_start; | │ │ │ │ │ -|int leafs_size; | │ │ │ │ │ -| int root_index; | │ │ │ │ │ -| std::tie(leafs_start, leafs_size, root_index) = | │ │ │ │ │ -| merkle_find_known_subtree(m_tree, block_index, m_num_blocks); | │ │ │ │ │ -| | │ │ │ │ │ -| // if the root node is unknown the hashes cannot be verified yet | │ │ │ │ │ -| if (m_tree[root_index].is_all_zeros()) | │ │ │ │ │ -| return std::make_tuple(set_block_result::unknown, leafs_start, leafs_size); | │ │ │ │ │ -| | │ │ │ │ │ -| // save the root hash because merkle_fill_tree will overwrite it | │ │ │ │ │ -| sha256_hash const root = m_tree[root_index]; | │ │ │ │ │ -| merkle_fill_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ -| | │ │ │ │ │ -| if (root != m_tree[root_index]) | │ │ │ │ │ +| else | │ │ │ │ │ | { | │ │ │ │ │ -| // hash failure, clear all the internal nodes | │ │ │ │ │ -| // the whole piece failed the hash check. Clear all block hashes | │ │ │ │ │ -| // in this piece and report a hash failure | │ │ │ │ │ -| merkle_clear_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ -| m_tree[root_index] = root; | │ │ │ │ │ -| return std::make_tuple(set_block_result::hash_failed, leafs_start, leafs_size); | │ │ │ │ │ -|_ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_e_r_k_l_e___t_r_e_e_._c_p_p_:_5_3_9_ _ _ _ _|_t_h_i_s_ _c_o_u_l_d_ _b_e_ _d_o_n_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_l_y_ _i_f_ _b_i_t_f_i_e_l_d_ _h_a_d_ _a_ _f_u_n_c_t_i_o_n_ _t_o_ _s_e_t_ _a_ _r_a_n_g_e_ _o_f_ _b_i_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss ccoouulldd bbee ddoonnee mmoorree eeffffiicciieennttllyy iiff bbiittffiieelldd hhaadd aa ffuunnccttiioonn ttoo sseett aa rraannggee ooff bbiittss ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmeerrkkllee__ttrreeee..ccpppp::553399 ****** | │ │ │ │ │ -|merkle_find_known_subtree(m_tree, block_index, m_num_blocks); | │ │ │ │ │ -| | │ │ │ │ │ -| // if the root node is unknown the hashes cannot be verified yet | │ │ │ │ │ -| if (m_tree[root_index].is_all_zeros()) | │ │ │ │ │ -| return std::make_tuple(set_block_result::unknown, leafs_start, leafs_size); | │ │ │ │ │ -| | │ │ │ │ │ -| // save the root hash because merkle_fill_tree will overwrite it | │ │ │ │ │ -| sha256_hash const root = m_tree[root_index]; | │ │ │ │ │ -| merkle_fill_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ +| m_stats_counters.set_value(counters::num_unchoke_slots | │ │ │ │ │ +| , allowed_upload_slots); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| if (root != m_tree[root_index]) | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| if (should_log()) | │ │ │ │ │ | { | │ │ │ │ │ -| // hash failure, clear all the internal nodes | │ │ │ │ │ -| // the whole piece failed the hash check. Clear all block hashes | │ │ │ │ │ -| // in this piece and report a hash failure | │ │ │ │ │ -| merkle_clear_tree(m_tree, leafs_size, first_leaf + leafs_start); | │ │ │ │ │ -| m_tree[root_index] = root; | │ │ │ │ │ -| return std::make_tuple(set_block_result::hash_failed, leafs_start, leafs_size); | │ │ │ │ │ +| session_log("RECALCULATE UNCHOKE SLOTS: [ peers: %d " | │ │ │ │ │ +| "eligible-peers: %d" | │ │ │ │ │ +| " allowed-slots: %d ]" | │ │ │ │ │ +| , int(m_connections.size()) | │ │ │ │ │ +|_ _ _ _ _,_ _i_n_t_(_p_e_e_r_s_._s_i_z_e_(_)_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| | |it might be a nice feature here to limit the number of torrents to send in a single update. By just posting the first n torrents, | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_4_7_8_6 |they would nicely be round-robined because the torrent lists are always pushed back. Perhaps the status_update_alert could even have| │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_a_ _f_i_x_e_d_ _a_r_r_a_y_ _o_f_ _n_ _e_n_t_r_i_e_s_ _r_a_t_h_e_r_ _t_h_a_n_ _a_ _v_e_c_t_o_r_,_ _t_o_ _f_u_r_t_h_e_r_ _i_m_p_r_o_v_e_ _m_e_m_o_r_y_ _l_o_c_a_l_i_t_y_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt mmiigghhtt bbee aa nniiccee ffeeaattuurree hheerree ttoo lliimmiitt tthhee nnuummbbeerr ooff ttoorrrreennttss ttoo sseenndd iinn aa ssiinnggllee uuppddaattee.. BByy jjuusstt ppoossttiinngg tthhee ffiirrsstt nn ttoorrrreennttss,, tthheeyy wwoouulldd nniicceellyy bbee rroouunndd--rroobbiinneedd | │ │ │ │ │ +|bbeeccaauussee tthhee ttoorrrreenntt lliissttss aarree aallwwaayyss ppuusshheedd bbaacckk.. PPeerrhhaappss tthhee ssttaattuuss__uuppddaattee__aalleerrtt ccoouulldd eevveenn hhaavvee aa ffiixxeedd aarrrraayy ooff nn eennttrriieess rraatthheerr tthhaann aa vveeccttoorr,, ttoo ffuurrtthheerr iimmpprroovvee mmeemmoorryy | │ │ │ │ │ +|llooccaalliittyy.. ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::44778866 ****** | │ │ │ │ │ +|t->status(&st, flags); | │ │ │ │ │ | } | │ │ │ │ │ -| | │ │ │ │ │ -|int const leafs_end = std::min(m_num_blocks, leafs_start + leafs_size); | │ │ │ │ │ -|for (int i = leafs_start; i < leafs_end; ++i) | │ │ │ │ │ -| m_block_verified.set_bit(i); | │ │ │ │ │ -| | │ │ │ │ │ -| // attempting to optimize storage is quite costly, only do it if we have | │ │ │ │ │ -| // a reason to believe it might have an effect | │ │ │ │ │ -| if (block_index == m_num_blocks - 1 || !m_tree[block_tree_index + 1].is_all_zeros()) | │ │ │ │ │ -| optimize_storage(); | │ │ │ │ │ -| | │ │ │ │ │ -| return std::make_tuple(set_block_result::ok, leafs_start, leafs_size); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| std::size_t merkle_tree::size() const | │ │ │ │ │ -| { | │ │ │ │ │ -| return static_cast(merkle_num_nodes(merkle_num_leafs(m_num_blocks))); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| int merkle_tree::num_pieces() const | │ │ │ │ │ -| { | │ │ │ │ │ -| int const ps = blocks_per_piece(); | │ │ │ │ │ -| TORRENT_ASSERT(ps > 0); | │ │ │ │ │ -| return (m_num_blocks + ps - 1) >> m_blocks_per_piece_log; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| int merkle_tree::block_layer_start() const | │ │ │ │ │ -| { | │ │ │ │ │ -| int const num_leafs = merkle_num_leafs(m_num_blocks); | │ │ │ │ │ -| TORRENT_ASSERT(num_leafs > 0); | │ │ │ │ │ -| return merkle_first_leaf(num_leafs); | │ │ │ │ │ -|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_e___c_r_y_p_t_o_._c_p_p_:_6_0_ _ _ _ _ _ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _g_e_t_ _t_h_e_ _l_i_t_e_r_a_l_ _w_o_r_k_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo ggeett tthhee lliitteerraall wwoorrkkiinngg ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppee__ccrryyppttoo..ccpppp::6600 ****** | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -| | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -| | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|#include "libtorrent/random.hpp" | │ │ │ │ │ -|#include "libtorrent/aux_/alloca.hpp" | │ │ │ │ │ -|#include "libtorrent/pe_crypto.hpp" | │ │ │ │ │ -|#include "libtorrent/hasher.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ -| | │ │ │ │ │ -| namespace mp = boost::multiprecision; | │ │ │ │ │ -| | │ │ │ │ │ -| namespace { | │ │ │ │ │ -|key_t const dh_prime | │ │ │ │ │ -|("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63|36210000000000090563"); │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| std::array export_key(key_t const& k) | │ │ │ │ │ +| void session_impl::post_torrent_updates(status_flags_t const flags) | │ │ │ │ │ | { | │ │ │ │ │ -| std::array ret; | │ │ │ │ │ -| auto* begin = reinterpret_cast(ret.data()); | │ │ │ │ │ -|_ _ _s_t_d_:_:_u_i_n_t_8___t_*_ _e_n_d_ _=_ _m_p_:_:_e_x_p_o_r_t___b_i_t_s_(_k_,_ _b_e_g_i_n_,_ _8_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_e___c_r_y_p_t_o_._c_p_p_:_7_1_ _ _ _ _ _ _ _|_i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _b_e_ _a_b_l_e_ _t_o_ _e_x_p_o_r_t_ _t_o_ _a_ _f_i_x_e_d_ _w_i_d_t_h_ _f_i_e_l_d_,_ _s_o_ _w_e_ _w_o_u_l_d_n_'_t_ _h_a_v_e_ _t_o_ _s_h_i_f_t_ _i_t_ _l_a_t_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo bbee aabbllee ttoo eexxppoorrtt ttoo aa ffiixxeedd wwiiddtthh ffiieelldd,, ssoo wwee wwoouullddnn''tt hhaavvee ttoo sshhiifftt iitt llaatteerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//ppee__ccrryyppttoo..ccpppp::7711 ****** | │ │ │ │ │ -|#include "libtorrent/random.hpp" | │ │ │ │ │ -|#include "libtorrent/aux_/alloca.hpp" | │ │ │ │ │ -|#include "libtorrent/pe_crypto.hpp" | │ │ │ │ │ -|#include "libtorrent/hasher.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ -| | │ │ │ │ │ -| namespace mp = boost::multiprecision; | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ | | │ │ │ │ │ -| namespace { | │ │ │ │ │ -| key_t const dh_prime | │ │ │ │ │ -| | │ │ │ │ │ -|("0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63|36210000000000090563"); │ │ │ │ │ -| } | │ │ │ │ │ +| TORRENT_ASSERT(is_single_thread()); | │ │ │ │ │ | | │ │ │ │ │ -| std::array export_key(key_t const& k) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::array ret; | │ │ │ │ │ -| auto* begin = reinterpret_cast(ret.data()); | │ │ │ │ │ -| std::uint8_t* end = mp::export_bits(k, begin, 8); | │ │ │ │ │ +| std::vector& state_updates | │ │ │ │ │ +| = m_torrent_lists[aux::session_impl::torrent_state_updates]; | │ │ │ │ │ | | │ │ │ │ │ -|if (end < begin + 96) | │ │ │ │ │ -|{ | │ │ │ │ │ -| int const len = int(end - begin); | │ │ │ │ │ -|#if defined __GNUC__ && __GNUC__ == 12 | │ │ │ │ │ -|#pragma GCC diagnostic push | │ │ │ │ │ -|#pragma GCC diagnostic ignored "-Wstringop-overflow" | │ │ │ │ │ -|#endif | │ │ │ │ │ -| std::memmove(begin + 96 - len, begin, aux::numeric_cast(len)); | │ │ │ │ │ -|#if defined __GNUC__ && __GNUC__ == 12 | │ │ │ │ │ -|#pragma GCC diagnostic pop | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| m_posting_torrent_updates = true; | │ │ │ │ │ |#endif | │ │ │ │ │ -| std::memset(begin, 0, aux::numeric_cast(96 - len)); | │ │ │ │ │ -| } | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void rc4_init(const unsigned char* in, std::size_t len, rc4 *state); | │ │ │ │ │ -| std::size_t rc4_encrypt(unsigned char *out, std::size_t outlen, rc4 *state); | │ │ │ │ │ -| | │ │ │ │ │ -| // Set the prime P and the generator, generate local public key | │ │ │ │ │ -| dh_key_exchange::dh_key_exchange() | │ │ │ │ │ -| { | │ │ │ │ │ -| aux::array random_key; | │ │ │ │ │ -| aux::random_bytes({reinterpret_cast(random_key.data()) | │ │ │ │ │ -| , static_cast(random_key.size())}); | │ │ │ │ │ -| | │ │ │ │ │ -| // create local key (random) | │ │ │ │ │ -| mp::import_bits(m_dh_local_secret, random_key.begin(), random_key.end()); | │ │ │ │ │ | | │ │ │ │ │ -| // key = (2 ^ secret) % prime | │ │ │ │ │ -|_ _ _m___d_h___l_o_c_a_l___k_e_y_ _=_ _m_p_:_:_p_o_w_m_(_k_e_y___t_(_2_)_,_ _m___d_h___l_o_c_a_l___s_e_c_r_e_t_,_ _d_h___p_r_i_m_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:_4_5_7_ _ _ _|_m_a_y_b_e_ _i_t_ _w_o_u_l_d_ _b_e_ _n_i_c_e_ _t_o_ _h_a_v_e_ _a_ _b_e_t_t_e_r_ _i_n_d_e_x_ _h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmaayybbee iitt wwoouulldd bbee nniiccee ttoo hhaavvee aa bbeetttteerr iinnddeexx hheerree ********** | │ │ │ │ │ -|****** ....//ssrrcc//ffiillee__ssttoorraaggee..ccpppp::445577 ****** | │ │ │ │ │ -|// find the file iterator and file offset | │ │ │ │ │ -| aux::file_entry target; | │ │ │ │ │ -| target.offset = aux::numeric_cast(offset); | │ │ │ │ │ -| TORRENT_ASSERT(!compare_file_offset(target, m_files.front())); | │ │ │ │ │ -| | │ │ │ │ │ -| auto file_iter = std::upper_bound( | │ │ │ │ │ -| m_files.begin(), m_files.end(), target, compare_file_offset); | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(file_iter != m_files.begin()); | │ │ │ │ │ -| --file_iter; | │ │ │ │ │ -| return file_index_t{int(file_iter - m_files.begin())}; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| file_index_t file_storage::file_index_at_piece(piece_index_t const piece) const | │ │ │ │ │ -| { | │ │ │ │ │ -| return file_index_at_offset(static_cast(piece) * std::int64_t(piece_length())); | │ │ │ │ │ -| } | │ │ │ │ │ +| std::vector status; | │ │ │ │ │ +| status.reserve(state_updates.size()); | │ │ │ │ │ | | │ │ │ │ │ -| file_index_t file_storage::file_index_for_root(sha256_hash const& root_hash) const | │ │ │ │ │ -| { | │ │ │ │ │ -|for (file_index_t const i : file_range()) | │ │ │ │ │ +|for (auto& t : state_updates) | │ │ │ │ │ |{ | │ │ │ │ │ -| if (root(i) == root_hash) return i; | │ │ │ │ │ +| TORRENT_ASSERT(t->m_links[aux::session_impl::torrent_state_updates].in_list()); | │ │ │ │ │ +| status.emplace_back(); | │ │ │ │ │ +| // querying accurate download counters may require | │ │ │ │ │ +| // the torrent to be loaded. Loading a torrent, and evicting another | │ │ │ │ │ +| // one will lead to calling state_updated(), which screws with | │ │ │ │ │ +| // this list while we're working on it, and break things | │ │ │ │ │ +| t->status(&status.back(), flags); | │ │ │ │ │ +| t->clear_in_state_update(); | │ │ │ │ │ | } | │ │ │ │ │ -| return file_index_t{-1}; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| piece_index_t file_storage::piece_index_at_file(file_index_t f) const | │ │ │ │ │ -| { | │ │ │ │ │ -| return piece_index_t{aux::numeric_cast(file_offset(f) / piece_length())}; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION <= 2 | │ │ │ │ │ -| char const* file_storage::file_name_ptr(file_index_t const index) const | │ │ │ │ │ -| { | │ │ │ │ │ -| return m_files[index].name; | │ │ │ │ │ -| } | │ │ │ │ │ +| state_updates.clear(); | │ │ │ │ │ | | │ │ │ │ │ -| int file_storage::file_name_len(file_index_t const index) const | │ │ │ │ │ -| { | │ │ │ │ │ -| if (m_files[index].name_len == aux::file_entry::name_is_owned) | │ │ │ │ │ -| return -1; | │ │ │ │ │ -| return m_files[index].name_len; | │ │ │ │ │ -| } | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS | │ │ │ │ │ +| m_posting_torrent_updates = false; | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| std::vector file_storage::map_block(piece_index_t const piece | │ │ │ │ │ -| , std::int64_t const offset, std::int64_t size) const | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT_PRECOND(piece >= piece_index_t{0}); | │ │ │ │ │ -|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T___P_R_E_C_O_N_D_(_p_i_e_c_e_ _<_ _e_n_d___p_i_e_c_e_(_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:_1_2_4_2_ _ _|_t_h_i_s_ _w_o_u_l_d_ _b_e_ _m_o_r_e_ _e_f_f_i_c_i_e_n_t_ _i_f_ _m___p_a_t_h_s_ _w_a_s_ _s_o_r_t_e_d_ _f_i_r_s_t_,_ _s_u_c_h_ _t_h_a_t_ _a_ _l_o_w_e_r_ _p_a_t_h_ _i_n_d_e_x_ _a_l_w_a_y_s_ _m_e_a_n_t_ _s_o_r_t_e_d_-_b_e_f_o_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss wwoouulldd bbee mmoorree eeffffiicciieenntt iiff mm__ppaatthhss wwaass ssoorrtteedd ffiirrsstt,, ssuucchh tthhaatt aa lloowweerr ppaatthh iinnddeexx aallwwaayyss mmeeaanntt ssoorrtteedd--bbeeffoorree ********** | │ │ │ │ │ -|****** ....//ssrrcc//ffiillee__ssttoorraaggee..ccpppp::11224422 ****** | │ │ │ │ │ -|} | │ │ │ │ │ +| m_alerts.emplace_alert(std::move(status)); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| void file_storage::canonicalize_impl(bool const backwards_compatible) | │ │ │ │ │ +| void session_impl::post_session_stats() | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(piece_length() >= 16 * 1024); | │ │ │ │ │ -| | │ │ │ │ │ -| // use this vector to track the new ordering of files | │ │ │ │ │ -| // this allows the use of STL algorithms despite them | │ │ │ │ │ -| // not supporting a custom swap functor | │ │ │ │ │ -| aux::vector new_order(end_file()); | │ │ │ │ │ -| for (auto i : file_range()) | │ │ │ │ │ -| new_order[i] = i; | │ │ │ │ │ -| | │ │ │ │ │ -| // remove any existing pad files | │ │ │ │ │ +| if (!m_posted_stats_header) | │ │ │ │ │ | { | │ │ │ │ │ -| auto pad_begin = std::partition(new_order.begin(), new_order.end() | │ │ │ │ │ -| , [this](file_index_t i) { return !m_files[i].pad_file; }); | │ │ │ │ │ -| new_order.erase(pad_begin, new_order.end()); | │ │ │ │ │ +| m_posted_stats_header = true; | │ │ │ │ │ +| m_alerts.emplace_alert(); | │ │ │ │ │ | } | │ │ │ │ │ +| m_disk_thread->update_stats_counters(m_stats_counters); | │ │ │ │ │ | | │ │ │ │ │ -| | │ │ │ │ │ -|// sort files by path/name | │ │ │ │ │ -| std::sort(new_order.begin(), new_order.end() | │ │ │ │ │ -| , [this](file_index_t l, file_index_t r) | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +|_ _ _i_f_ _(_m___d_h_t_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_1_6_1_ _ _|_f_a_c_t_o_r_ _o_u_t_ _t_h_i_s_ _l_o_g_i_c_ _i_n_t_o_ _a_ _s_e_p_a_r_a_t_e_ _f_u_n_c_t_i_o_n_ _f_o_r_ _u_n_i_t_ _t_e_s_t_i_n_g_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ffaaccttoorr oouutt tthhiiss llooggiicc iinnttoo aa sseeppaarraattee ffuunnccttiioonn ffoorr uunniitt tteessttiinngg ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55116611 ****** | │ │ │ │ │ +|if (m_settings.get_int(settings_pack::outgoing_port) > 0) | │ │ │ │ │ | { | │ │ │ │ │ -| // assuming m_paths are unique! | │ │ │ │ │ -| auto const& lf = m_files[l]; | │ │ │ │ │ -| auto const& rf = m_files[r]; | │ │ │ │ │ -| if (lf.path_index != rf.path_index) | │ │ │ │ │ -| { | │ │ │ │ │ -| int const ret = path_compare(m_paths[lf.path_index], lf.filename() | │ │ │ │ │ -| , m_paths[rf.path_index], rf.filename()); | │ │ │ │ │ -| if (ret != 0) return ret < 0; | │ │ │ │ │ -| } | │ │ │ │ │ -| return lf.filename() < rf.filename(); | │ │ │ │ │ -| }); | │ │ │ │ │ -| | │ │ │ │ │ -| aux::vector new_files; | │ │ │ │ │ -| aux::vector new_file_hashes; | │ │ │ │ │ -| aux::vector new_mtime; | │ │ │ │ │ -| | │ │ │ │ │ -| // reserve enough space for the worst case after padding | │ │ │ │ │ -| new_files.reserve(new_order.size() * 2 - 1); | │ │ │ │ │ -| if (!m_file_hashes.empty()) | │ │ │ │ │ -| new_file_hashes.reserve(new_order.size() * 2 - 1); | │ │ │ │ │ -| if (!m_mtime.empty()) | │ │ │ │ │ -| new_mtime.reserve(new_order.size() * 2 - 1); | │ │ │ │ │ -| | │ │ │ │ │ -| // re-compute offsets and insert pad files as necessary | │ │ │ │ │ -|_ _ _s_t_d_:_:_i_n_t_6_4___t_ _o_f_f_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_f_i_l_e___s_t_o_r_a_g_e_._c_p_p_:_1_3_4_5_ _ _|_i_n_ _C_+_+_1_7_ _t_h_i_s_ _c_o_u_l_d_ _b_e_ _s_t_r_i_n_g___v_i_e_w_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinn CC++++1177 tthhiiss ccoouulldd bbee ssttrriinngg__vviieeww ********** | │ │ │ │ │ -|****** ....//ssrrcc//ffiillee__ssttoorraaggee..ccpppp::11334455 ****** | │ │ │ │ │ -|add_pad_file(i); | │ │ │ │ │ +|#ifdef TORRENT_WINDOWS | │ │ │ │ │ +| s.set_option(exclusive_address_use(true), ec); | │ │ │ │ │ +|#else | │ │ │ │ │ +| s.set_option(tcp::acceptor::reuse_address(true), ec); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| // ignore errors because the underlying socket may not | │ │ │ │ │ +| // be opened yet. This happens when we're routing through | │ │ │ │ │ +| // a proxy. In that case, we don't yet know the address of | │ │ │ │ │ +| // the proxy server, and more importantly, we don't know | │ │ │ │ │ +| // the address family of its address. This means we can't | │ │ │ │ │ +| // open the socket yet. The socks abstraction layer defers | │ │ │ │ │ +| // opening it. | │ │ │ │ │ +| ec.clear(); | │ │ │ │ │ +| bind_ep.port(std::uint16_t(next_port())); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| m_files = std::move(new_files); | │ │ │ │ │ -| m_file_hashes = std::move(new_file_hashes); | │ │ │ │ │ -| m_mtime = std::move(new_mtime); | │ │ │ │ │ -| | │ │ │ │ │ -| m_total_size = off; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void file_storage::sanitize_symlinks() | │ │ │ │ │ -| { | │ │ │ │ │ -| // symlinks are unusual, this function is optimized assuming there are no | │ │ │ │ │ -| // symbolic links in the torrent. If we find one symbolic link, we'll | │ │ │ │ │ -| // build the hash table of files it's allowed to refer to, but don't pay | │ │ │ │ │ -| // that price up-front. | │ │ │ │ │ -| std::unordered_map file_map; | │ │ │ │ │ -| bool file_map_initialized = false; | │ │ │ │ │ -| | │ │ │ │ │ -| // lazily instantiated set of all valid directories a symlink may point to | │ │ │ │ │ -|std::unordered_set dir_map; | │ │ │ │ │ -|bool dir_map_initialized = false; | │ │ │ │ │ -| | │ │ │ │ │ -| // symbolic links that points to directories | │ │ │ │ │ -| std::unordered_map dir_links; | │ │ │ │ │ -| | │ │ │ │ │ -| // we validate symlinks in (potentially) 2 passes over the files. | │ │ │ │ │ -| // remaining symlinks to validate after the first pass | │ │ │ │ │ -| std::vector symlinks_to_validate; | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const i : file_range()) | │ │ │ │ │ +| if (is_utp(s)) | │ │ │ │ │ | { | │ │ │ │ │ -| if (!(file_flags(i) & file_storage::flag_symlink)) continue; | │ │ │ │ │ | | │ │ │ │ │ -| if (!file_map_initialized) | │ │ │ │ │ +|utp_socket_impl* impl = nullptr; | │ │ │ │ │ +| transport ssl = transport::plaintext; | │ │ │ │ │ +|#if TORRENT_USE_SSL | │ │ │ │ │ +| if (boost::get>(&s) != nullptr) | │ │ │ │ │ | { | │ │ │ │ │ -| for (auto const j : file_range()) | │ │ │ │ │ -| file_map.insert({internal_file_path(j), j}); | │ │ │ │ │ -| file_map_initialized = true; | │ │ │ │ │ +| impl = boost::get>(s).next_layer().get_impl(); | │ │ │ │ │ +| ssl = transport::ssl; | │ │ │ │ │ | } | │ │ │ │ │ +| else | │ │ │ │ │ +|#endif | │ │ │ │ │ +| impl = boost::get(s).get_impl(); | │ │ │ │ │ | | │ │ │ │ │ -| aux::file_entry const& fe = m_files[i]; | │ │ │ │ │ -| TORRENT_ASSERT(fe.symlink_index < int(m_symlinks.size())); | │ │ │ │ │ -| | │ │ │ │ │ -| // symlink targets are only allowed to point to files or directories in | │ │ │ │ │ -| // this torrent. | │ │ │ │ │ +| std::vector> with_gateways; | │ │ │ │ │ +| std::shared_ptr match; | │ │ │ │ │ +| for (auto& ls : m_listen_sockets) | │ │ │ │ │ | { | │ │ │ │ │ -| std::string target = m_symlinks[fe.symlink_index]; | │ │ │ │ │ -| | │ │ │ │ │ -| if (is_complete(target)) | │ │ │ │ │ -|_ _ _ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_u_t_p___s_o_c_k_e_t___m_a_n_a_g_e_r_._c_p_p_:|this should not be heap allocated, sockets should be movable | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_2_0_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd nnoott bbee hheeaapp aallllooccaatteedd,, ssoocckkeettss sshhoouulldd bbee mmoovvaabbllee ********** | │ │ │ │ │ -|****** ....//ssrrcc//uuttpp__ssoocckkeett__mmaannaaggeerr..ccpppp::220044 ****** | │ │ │ │ │ -|// UTP_LOGV("incoming packet id:%d source:%s\n", id, print_endpoint(ep).c_str()); | │ │ │ │ │ -| | │ │ │ │ │ -| if (!m_sett.get_bool(settings_pack::enable_incoming_utp)) | │ │ │ │ │ -| return false; | │ │ │ │ │ -| | │ │ │ │ │ -| // if not found, see if it's a SYN packet, if it is, | │ │ │ │ │ -| // create a new utp_stream | │ │ │ │ │ -| if (ph->get_type() == ST_SYN) | │ │ │ │ │ -| { | │ │ │ │ │ -| // possible SYN flood. Just ignore | │ │ │ │ │ -| if (int(m_utp_sockets.size()) > m_sett.get_int(settings_pack::connections_limit) * 2) | │ │ │ │ │ -| return false; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(m_new_connection == -1); | │ │ │ │ │ -| // create the new socket with this ID | │ │ │ │ │ -| m_new_connection = id; | │ │ │ │ │ -| | │ │ │ │ │ -|// UTP_LOGV("not found, new connection id:%d\n", m_new_connection); | │ │ │ │ │ -| | │ │ │ │ │ -|aux::socket_type c(aux::instantiate_connection(m_ios, aux::proxy_settings(), m_ssl_context, this, true, false)); | │ │ │ │ │ +| // this is almost, but not quite, like can_route() | │ │ │ │ │ +| if (!(ls->flags & listen_socket_t::proxy) | │ │ │ │ │ +| && is_v4(ls->local_endpoint) != remote_address.is_v4()) | │ │ │ │ │ +| continue; | │ │ │ │ │ +| if (ls->ssl != ssl) continue; | │ │ │ │ │ +| if (!(ls->flags & listen_socket_t::local_network)) | │ │ │ │ │ +| with_gateways.push_back(ls); | │ │ │ │ │ | | │ │ │ │ │ -| utp_stream* str = nullptr; | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| if (is_ssl(c)) | │ │ │ │ │ -| str = &boost::get>(c).next_layer(); | │ │ │ │ │ -| else | │ │ │ │ │ +| if (ls->flags & listen_socket_t::proxy | │ │ │ │ │ +| || match_addr_mask(ls->local_endpoint.address(), remote_address, ls->netmask)) | │ │ │ │ │ +| { | │ │ │ │ │ +| // is this better than the previous match? | │ │ │ │ │ +| match = ls; | │ │ │ │ │ +|_ _ _ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_5_8_8_0_ _ _|_r_e_f_a_c_t_o_r_,_ _m_o_v_e_ _t_h_e_ _s_t_o_r_a_g_e_ _t_o_ _d_h_t___t_r_a_c_k_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** rreeffaaccttoorr,, mmoovvee tthhee ssttoorraaggee ttoo ddhhtt__ttrraacckkeerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::55888800 ****** | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| session_log("not starting DHT, outstanding router lookups: %d" | │ │ │ │ │ +| , m_outstanding_router_lookups); | │ │ │ │ │ |#endif | │ │ │ │ │ -| str = boost::get(&c); | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(str); | │ │ │ │ │ -| int const mtu = mtu_for_dest(ep.address()); | │ │ │ │ │ -| str->get_impl()->init_mtu(mtu); | │ │ │ │ │ -| str->get_impl()->m_sock = std::move(socket); | │ │ │ │ │ -| bool const ret = str->get_impl()->incoming_packet(p, ep, receive_time); | │ │ │ │ │ -| if (!ret) return false; | │ │ │ │ │ -| m_last_socket = str->get_impl(); | │ │ │ │ │ -| m_cb(std::move(c)); | │ │ │ │ │ -| // the connection most likely changed its connection ID here | │ │ │ │ │ -| // we need to move it to the correct ID | │ │ │ │ │ -| return true; | │ │ │ │ │ +| return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| if (ph->get_type() == ST_RESET) return false; | │ │ │ │ │ -| | │ │ │ │ │ -| // #error send reset | │ │ │ │ │ -| | │ │ │ │ │ -| return false; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|_ _v_o_i_d_ _u_t_p___s_o_c_k_e_t___m_a_n_a_g_e_r_:_:_s_u_b_s_c_r_i_b_e___w_r_i_t_a_b_l_e_(_u_t_p___s_o_c_k_e_t___i_m_p_l_*_ _s_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_m_m_a_p___d_i_s_k___i_o_._c_p_p_:_5_7_8_ _ _ _|_i_n_ _t_h_e_ _f_u_t_u_r_e_,_ _p_r_o_p_a_g_a_t_e_ _e_x_c_e_p_t_i_o_n_s_ _b_a_c_k_ _t_o_ _t_h_e_ _h_a_n_d_l_e_r_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinn tthhee ffuuttuurree,, pprrooppaaggaattee eexxcceeppttiioonnss bbaacckk ttoo tthhee hhaannddlleerrss ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmmmaapp__ddiisskk__iioo..ccpppp::557788 ****** | │ │ │ │ │ -|#if DEBUG_DISK_THREAD | │ │ │ │ │ +| if (m_abort) | │ │ │ │ │ | { | │ │ │ │ │ -| std::unique_lock l(m_job_mutex); | │ │ │ │ │ -| | │ │ │ │ │ -| DLOG("perform_job job: %s ( %s%s) piece: %d offset: %d outstanding: %d\n" | │ │ │ │ │ -| , job_action_name[j->action] | │ │ │ │ │ -| , (j->flags & mmap_disk_job::fence) ? "fence ": "" | │ │ │ │ │ -| , (j->flags & mmap_disk_job::force_copy) ? "force_copy ": "" | │ │ │ │ │ -| , static_cast(j->piece), j->d.io.offset | │ │ │ │ │ -| , j->storage ? j->storage->num_outstanding_jobs() : -1); | │ │ │ │ │ -| } | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| session_log("not starting DHT, aborting"); | │ │ │ │ │ |#endif | │ │ │ │ │ +| return; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| std::shared_ptr storage = j->storage; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(static_cast(j->action) < int(job_functions.size())); | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| session_log("starting DHT, running: %s, router lookups: %d" | │ │ │ │ │ +| , m_dht ? "true" : "false", m_outstanding_router_lookups); | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| m_stats_counters.inc_stats_counter(counters::num_running_disk_jobs, 1); | │ │ │ │ │ +|m_dht_storage = m_dht_storage_constructor(m_settings); | │ │ │ │ │ +|m_dht = std::make_shared( | │ │ │ │ │ +| static_cast(this) | │ │ │ │ │ +| , m_io_context | │ │ │ │ │ +| , [this](aux::listen_socket_handle const& sock | │ │ │ │ │ +| , udp::endpoint const& ep | │ │ │ │ │ +| , span p | │ │ │ │ │ +| , error_code& ec | │ │ │ │ │ +| , udp_send_flags_t const flags) | │ │ │ │ │ +| { send_udp_packet_listen(sock, ep, p, ec, flags); } | │ │ │ │ │ +| , m_settings | │ │ │ │ │ +| , m_stats_counters | │ │ │ │ │ +| , *m_dht_storage | │ │ │ │ │ +| , std::move(m_dht_state)); | │ │ │ │ │ | | │ │ │ │ │ -| // call disk function | │ │ │ │ │ -|status_t ret = status_t::no_error; | │ │ │ │ │ -|try | │ │ │ │ │ -| { | │ │ │ │ │ -| int const idx = static_cast(j->action); | │ │ │ │ │ -| ret = (this->*(job_functions[static_cast(idx)]))(j); | │ │ │ │ │ -| } | │ │ │ │ │ -| catch (boost::system::system_error const& err) | │ │ │ │ │ -| { | │ │ │ │ │ -| ret = status_t::fatal_disk_error; | │ │ │ │ │ -| j->error.ec = err.code(); | │ │ │ │ │ -| j->error.operation = operation_t::exception; | │ │ │ │ │ -| } | │ │ │ │ │ -| catch (std::bad_alloc const&) | │ │ │ │ │ +| for (auto& s : m_listen_sockets) | │ │ │ │ │ | { | │ │ │ │ │ -| ret = status_t::fatal_disk_error; | │ │ │ │ │ -| j->error.ec = errors::no_memory; | │ │ │ │ │ -| j->error.operation = operation_t::exception; | │ │ │ │ │ +| if (s->ssl != transport::ssl | │ │ │ │ │ +| && !(s->flags & listen_socket_t::local_network)) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_dht->new_socket(s); | │ │ │ │ │ +| } | │ │ │ │ │ | } | │ │ │ │ │ -| catch (std::exception const&) | │ │ │ │ │ +| | │ │ │ │ │ +| for (auto const& n : m_dht_router_nodes) | │ │ │ │ │ | { | │ │ │ │ │ -| ret = status_t::fatal_disk_error; | │ │ │ │ │ -| j->error.ec = boost::asio::error::fault; | │ │ │ │ │ -| j->error.operation = operation_t::exception; | │ │ │ │ │ +| m_dht->add_router_node(n); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| // note that -2 errors are OK | │ │ │ │ │ -| TORRENT_ASSERT(ret != status_t::fatal_disk_error | │ │ │ │ │ -| || (j->error.ec && j->error.operation != operation_t::unknown)); | │ │ │ │ │ -| | │ │ │ │ │ -|_ _ _m___s_t_a_t_s___c_o_u_n_t_e_r_s_._i_n_c___s_t_a_t_s___c_o_u_n_t_e_r_(_c_o_u_n_t_e_r_s_:_:_n_u_m___r_u_n_n_i_n_g___d_i_s_k___j_o_b_s_,_ _-_1_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_m_m_a_p___d_i_s_k___i_o_._c_p_p_:_1_0_1_7 |this is potentially very expensive. One way to solve it would be to have a fence for just this one piece. but it hardly seems worth | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_h_e_ _c_o_m_p_l_e_x_i_t_y_ _a_n_d_ _c_o_s_t_ _j_u_s_t_ _f_o_r_ _t_h_e_ _e_d_g_e_ _c_a_s_e_ _o_f_ _r_e_c_e_i_v_i_n_g_ _a_ _c_o_r_r_u_p_t_ _p_i_e_c_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss iiss ppootteennttiiaallllyy vveerryy eexxppeennssiivvee.. OOnnee wwaayy ttoo ssoollvvee iitt wwoouulldd bbee ttoo hhaavvee aa ffeennccee ffoorr jjuusstt tthhiiss oonnee ppiieeccee.. bbuutt iitt hhaarrddllyy sseeeemmss wwoorrtthh tthhee ccoommpplleexxiittyy aanndd ccoosstt jjuusstt ffoorr tthhee | │ │ │ │ │ -|eeddggee ccaassee ooff rreecceeiivviinngg aa ccoorrrruupptt ppiieeccee ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmmmaapp__ddiisskk__iioo..ccpppp::11001177 ****** | │ │ │ │ │ -|aux::mmap_disk_job* j = m_job_pool.allocate_job(aux::job_action_t::file_priority); | │ │ │ │ │ -| j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ -| j->argument = std::move(prios); | │ │ │ │ │ -| j->callback = std::move(handler); | │ │ │ │ │ -| | │ │ │ │ │ -| add_fence_job(j); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void mmap_disk_io::async_clear_piece(storage_index_t const storage | │ │ │ │ │ -| , piece_index_t const index, std::function handler) | │ │ │ │ │ -| { | │ │ │ │ │ -| aux::mmap_disk_job* j = m_job_pool.allocate_job(aux::job_action_t::clear_piece); | │ │ │ │ │ -| j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ -| j->piece = index; | │ │ │ │ │ -| j->callback = std::move(handler); | │ │ │ │ │ -| | │ │ │ │ │ -| // regular jobs are not guaranteed to be executed in-order | │ │ │ │ │ -| // since clear piece must guarantee that all write jobs that | │ │ │ │ │ -| // have been issued finish before the clear piece job completes | │ │ │ │ │ -| | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_m_m_a_p___d_i_s_k___i_o_._c_p_p_:_1_0_2_2 |Perhaps the job queue could be traversed and all jobs for this piece could be cancelled. If there are no threads currently writing | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_t_o_ _t_h_i_s_ _p_i_e_c_e_,_ _w_e_ _c_o_u_l_d_ _s_k_i_p_ _t_h_e_ _f_e_n_c_e_ _a_l_t_o_g_e_t_h_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** PPeerrhhaappss tthhee jjoobb qquueeuuee ccoouulldd bbee ttrraavveerrsseedd aanndd aallll jjoobbss ffoorr tthhiiss ppiieeccee ccoouulldd bbee ccaanncceelllleedd.. IIff tthheerree aarree nnoo tthhrreeaaddss ccuurrrreennttllyy wwrriittiinngg ttoo tthhiiss ppiieeccee,, wwee ccoouulldd sskkiipp tthhee ffeennccee| │ │ │ │ │ -|aallttooggeetthheerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//mmmmaapp__ddiisskk__iioo..ccpppp::11002222 ****** | │ │ │ │ │ -|j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ -| j->argument = std::move(prios); | │ │ │ │ │ -| j->callback = std::move(handler); | │ │ │ │ │ -| | │ │ │ │ │ -| add_fence_job(j); | │ │ │ │ │ +| for (auto const& n : m_dht_nodes) | │ │ │ │ │ +|_ _ _{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_s_e_s_s_i_o_n___i_m_p_l_._c_p_p_:_6_2_6_7_ _ _|_a_s_s_e_r_t_s_ _t_h_a_t_ _n_o_ _o_u_t_s_t_a_n_d_i_n_g_ _a_s_y_n_c_ _o_p_e_r_a_t_i_o_n_s_ _a_r_e_ _s_t_i_l_l_ _i_n_ _f_l_i_g_h_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aasssseerrttss tthhaatt nnoo oouuttssttaannddiinngg aassyynncc ooppeerraattiioonnss aarree ssttiillll iinn fflliigghhtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//sseessssiioonn__iimmppll..ccpppp::66226677 ****** | │ │ │ │ │ +|if (!m_dht) return; | │ │ │ │ │ +| m_dht->direct_request(ep, e, std::bind(&on_direct_response, std::ref(m_alerts), userdata, _1)); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void mmap_disk_io::async_clear_piece(storage_index_t const storage | │ │ │ │ │ -| , piece_index_t const index, std::function handler) | │ │ │ │ │ -| { | │ │ │ │ │ -| aux::mmap_disk_job* j = m_job_pool.allocate_job(aux::job_action_t::clear_piece); | │ │ │ │ │ -| j->storage = m_torrents[storage]->shared_from_this(); | │ │ │ │ │ -| j->piece = index; | │ │ │ │ │ -| j->callback = std::move(handler); | │ │ │ │ │ -| | │ │ │ │ │ -| // regular jobs are not guaranteed to be executed in-order | │ │ │ │ │ -| // since clear piece must guarantee that all write jobs that | │ │ │ │ │ -| // have been issued finish before the clear piece job completes | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|add_fence_job(j); | │ │ │ │ │ -|} | │ │ │ │ │ +|#endif | │ │ │ │ │ | | │ │ │ │ │ -| status_t mmap_disk_io::do_hash(aux::mmap_disk_job* j) | │ │ │ │ │ +| bool session_impl::is_listening() const | │ │ │ │ │ | { | │ │ │ │ │ -| // we're not using a cache. This is the simple path | │ │ │ │ │ -| // just read straight from the file | │ │ │ │ │ -| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -| | │ │ │ │ │ -| bool const v1 = bool(j->flags & disk_interface::v1_hash); | │ │ │ │ │ -| bool const v2 = !j->d.h.block_hashes.empty(); | │ │ │ │ │ -| | │ │ │ │ │ -| int const piece_size = v1 ? j->storage->files().piece_size(j->piece) : 0; | │ │ │ │ │ -| int const piece_size2 = v2 ? j->storage->files().piece_size2(j->piece) : 0; | │ │ │ │ │ -| int const blocks_in_piece = v1 ? (piece_size + default_block_size - 1) / default_block_size : 0; | │ │ │ │ │ -| int const blocks_in_piece2 = v2 ? j->storage->files().blocks_in_piece2(j->piece) : 0; | │ │ │ │ │ -| aux::open_mode_t const file_mode = file_mode_for_job(j); | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(!v2 || int(j->d.h.block_hashes.size()) >= blocks_in_piece2); | │ │ │ │ │ -| TORRENT_ASSERT(v1 || v2); | │ │ │ │ │ -| | │ │ │ │ │ -| hasher h; | │ │ │ │ │ -| int ret = 0; | │ │ │ │ │ -| int offset = 0; | │ │ │ │ │ -| int const blocks_to_read = std::max(blocks_in_piece, blocks_in_piece2); | │ │ │ │ │ -| time_point const start_time = clock_type::now(); | │ │ │ │ │ -| for (int i = 0; i < blocks_to_read; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| bool const v2_block = i < blocks_in_piece2; | │ │ │ │ │ +| return !m_listen_sockets.empty(); | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|_ _ _ _D_L_O_G_(_"_d_o___h_a_s_h_:_ _r_e_a_d_i_n_g_ _(_p_i_e_c_e_:_ _%_d_ _b_l_o_c_k_:_ _%_d_)_\_n_"_,_ _i_n_t_(_j_-_>_p_i_e_c_e_)_,_ _i_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/ |introduce a web-seed default class which has a low download priority | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_w_e_b___c_o_n_n_e_c_t_i_o_n___b_a_s_e_._c_p_p_:_7_2_ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinnttrroodduuccee aa wweebb--sseeeedd ddeeffaauulltt ccllaassss wwhhiicchh hhaass aa llooww ddoowwnnllooaadd pprriioorriittyy ********** | │ │ │ │ │ -|****** ....//ssrrcc//wweebb__ccoonnnneeccttiioonn__bbaassee..ccpppp::7722 ****** | │ │ │ │ │ -|: peer_connection(pack) | │ │ │ │ │ -| , m_first_request(true) | │ │ │ │ │ -| , m_ssl(false) | │ │ │ │ │ -| , m_external_auth(web.auth) | │ │ │ │ │ -| , m_extra_headers(web.extra_headers) | │ │ │ │ │ -| , m_parser(http_parser::dont_parse_chunks) | │ │ │ │ │ -| , m_body_start(0) | │ │ │ │ │ +| session_impl::~session_impl() | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(&web.peer_info == pack.peerinfo); | │ │ │ │ │ -| // when going through a proxy, we don't necessarily have an endpoint here, | │ │ │ │ │ -| // since the proxy might be resolving the hostname, not us | │ │ │ │ │ -| TORRENT_ASSERT(web.endpoints.empty() || web.endpoints.front() == pack.endp); | │ │ │ │ │ -| | │ │ │ │ │ -| INVARIANT_CHECK; | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(is_outgoing()); | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_ASSERT(!m_torrent.lock()->is_upload_only()); | │ │ │ │ │ -| | │ │ │ │ │ -| // we only want left-over bandwidth | │ │ │ │ │ -| | │ │ │ │ │ -|std::string protocol; | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| std::tie(protocol, m_basic_auth, m_host, m_port, m_path) | │ │ │ │ │ -| = parse_url_components(web.url, ec); | │ │ │ │ │ -| TORRENT_ASSERT(!ec); | │ │ │ │ │ +| // since we're destructing the session, no more alerts will make it out to | │ │ │ │ │ +| // the user. So stop posting them now | │ │ │ │ │ +| m_alerts.set_alert_mask({}); | │ │ │ │ │ +| m_alerts.set_notify_function({}); | │ │ │ │ │ | | │ │ │ │ │ -| if (m_port == -1 && protocol == "http") | │ │ │ │ │ -| m_port = 80; | │ │ │ │ │ +| // this is not allowed to be the network thread! | │ │ │ │ │ +|// TORRENT_ASSERT(is_not_thread()); | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_SSL | │ │ │ │ │ -| if (protocol == "https") | │ │ │ │ │ +|// this can happen if we end the io_context run loop with an exception | │ │ │ │ │ +| m_connections.clear(); | │ │ │ │ │ +| for (auto& t : m_torrents) | │ │ │ │ │ | { | │ │ │ │ │ -| m_ssl = true; | │ │ │ │ │ -| if (m_port == -1) m_port = 443; | │ │ │ │ │ +| t->panic(); | │ │ │ │ │ +| t->abort(); | │ │ │ │ │ | } | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| if (!m_basic_auth.empty()) | │ │ │ │ │ -| m_basic_auth = base64encode(m_basic_auth); | │ │ │ │ │ +| m_torrents.clear(); | │ │ │ │ │ | | │ │ │ │ │ -| m_server_string = m_host; | │ │ │ │ │ -| aux::verify_encoding(m_server_string); | │ │ │ │ │ -| } | │ │ │ │ │ +| // this has probably been called already, but in case of sudden | │ │ │ │ │ +| // termination through an exception, it may not have been done | │ │ │ │ │ +| abort_stage2(); | │ │ │ │ │ | | │ │ │ │ │ -| int web_connection_base::timeout() const | │ │ │ │ │ -| { | │ │ │ │ │ -| // since this is a web seed, change the timeout | │ │ │ │ │ -| // according to the settings. | │ │ │ │ │ -| return m_settings.get_int(settings_pack::urlseed_timeout); | │ │ │ │ │ -|_ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_t_o_r_r_e_n_t___i_n_f_o_._c_p_p_:_8_8_7_ _ _ _|_t_h_i_s_ _s_h_o_u_l_d_ _b_e_ _c_o_n_s_i_d_e_r_e_d_ _a_ _f_a_i_l_u_r_e_,_ _a_n_d_ _t_h_e_ _._t_o_r_r_e_n_t_ _f_i_l_e_ _r_e_j_e_c_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss sshhoouulldd bbee ccoonnssiiddeerreedd aa ffaaiilluurree,, aanndd tthhee ..ttoorrrreenntt ffiillee rreejjeecctteedd ********** | │ │ │ │ │ -|****** ....//ssrrcc//ttoorrrreenntt__iinnffoo..ccpppp::888877 ****** | │ │ │ │ │ -|std::string ext = extension(filename); | │ │ │ │ │ -| int cnt = 0; | │ │ │ │ │ -| for (;;) | │ │ │ │ │ +|#if defined TORRENT_ASIO_DEBUGGING | │ │ │ │ │ +| FILE* f = fopen("wakeups.log", "w+"); | │ │ │ │ │ +| if (f != nullptr) | │ │ │ │ │ +| { | │ │ │ │ │ +| time_point m = min_time(); | │ │ │ │ │ +| if (!_wakeups.empty()) m = _wakeups[0].timestamp; | │ │ │ │ │ +| time_point prev = m; | │ │ │ │ │ +| std::uint64_t prev_csw = 0; | │ │ │ │ │ +| if (!_wakeups.empty()) prev_csw = _wakeups[0].context_switches; | │ │ │ │ │ +| std::fprintf(f, "abs. time\trel. time\tctx switch\tidle-wakeup\toperation\n"); | │ │ │ │ │ +| for (wakeup_t const& w : _wakeups) | │ │ │ │ │ | { | │ │ │ │ │ -| ++cnt; | │ │ │ │ │ -| char new_ext[50]; | │ │ │ │ │ -| std::snprintf(new_ext, sizeof(new_ext), ".%d%s", cnt, ext.c_str()); | │ │ │ │ │ -| filename = base + new_ext; | │ │ │ │ │ -| | │ │ │ │ │ -| boost::crc_optimal<32, 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true> crc; | │ │ │ │ │ -| process_string_lowercase(crc, filename); | │ │ │ │ │ -| std::uint32_t const new_hash = crc.checksum(); | │ │ │ │ │ -| if (files.find(new_hash) == files.end()) | │ │ │ │ │ -| { | │ │ │ │ │ -| files.insert({new_hash, {i, 0}}); | │ │ │ │ │ -| break; | │ │ │ │ │ -| } | │ │ │ │ │ -| ++num_collisions; | │ │ │ │ │ -| if (num_collisions > 100) | │ │ │ │ │ -| { | │ │ │ │ │ -|} | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| copy_on_write(); | │ │ │ │ │ -| m_files.rename_file(i, filename); | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void torrent_info::remap_files(file_storage const& f) | │ │ │ │ │ -| { | │ │ │ │ │ +| bool const idle_wakeup = w.context_switches > prev_csw; | │ │ │ │ │ +| std::fprintf(f, "%" PRId64 "\t%" PRId64 "\t%" PRId64 "\t%c\t%s\n" | │ │ │ │ │ +| , total_microseconds(w.timestamp - m) | │ │ │ │ │ +| , total_microseconds(w.timestamp - prev) | │ │ │ │ │ +|_ _ _ _ _ _,_ _w_._c_o_n_t_e_x_t___s_w_i_t_c_h_e_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_p_a_c_k_e_t___b_u_f_f_e_r_._c_p_p_:_1_5_7_ _ _|_u_s_e_ _c_o_m_p_a_r_e___l_e_s_s___w_r_a_p_ _f_o_r_ _t_h_i_s_ _c_o_m_p_a_r_i_s_o_n_ _a_s_ _w_e_l_l_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** uussee ccoommppaarree__lleessss__wwrraapp ffoorr tthhiiss ccoommppaarriissoonn aass wweellll ********** | │ │ │ │ │ +|****** ....//ssrrcc//ppaacckkeett__bbuuffffeerr..ccpppp::115577 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ | INVARIANT_CHECK; | │ │ │ │ │ +| TORRENT_ASSERT_VAL(size <= 0xffff, size); | │ │ │ │ │ +| std::uint32_t new_size = m_capacity == 0 ? 16 : m_capacity; | │ │ │ │ │ | | │ │ │ │ │ -| TORRENT_ASSERT(is_loaded()); | │ │ │ │ │ -| // the new specified file storage must have the exact | │ │ │ │ │ -| // same size as the current file storage | │ │ │ │ │ -| TORRENT_ASSERT(m_files.total_size() == f.total_size()); | │ │ │ │ │ -| | │ │ │ │ │ -| if (m_files.total_size() != f.total_size()) return; | │ │ │ │ │ -| copy_on_write(); | │ │ │ │ │ -| m_files = f; | │ │ │ │ │ -| m_files.set_num_pieces(m_orig_files->num_pieces()); | │ │ │ │ │ -| m_files.set_piece_length(m_orig_files->piece_length()); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| // standard constructor that parses a torrent file | │ │ │ │ │ -| torrent_info::torrent_info(entry const& torrent_file) | │ │ │ │ │ -| { | │ │ │ │ │ -| std::vector tmp; | │ │ │ │ │ -| std::back_insert_iterator> out(tmp); | │ │ │ │ │ -|_ _ _b_e_n_c_o_d_e_(_o_u_t_,_ _t_o_r_r_e_n_t___f_i_l_e_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_l_o_a_d___t_o_r_r_e_n_t_._c_p_p_:_1_2_1_ _ _ _|_m_o_v_e_ _t_h_e_ _l_o_a_d_i_n_g_ _l_o_g_i_c_ _f_r_o_m_ _t_o_r_r_e_n_t___i_n_f_o_ _c_o_n_s_t_r_u_c_t_o_r_ _i_n_t_o_ _h_e_r_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee tthhee llooaaddiinngg llooggiicc ffrroomm ttoorrrreenntt__iinnffoo ccoonnssttrruuccttoorr iinnttoo hheerree ********** | │ │ │ │ │ -|****** ....//ssrrcc//llooaadd__ttoorrrreenntt..ccpppp::112211 ****** | │ │ │ │ │ -|mask.resize(std::size_t(full_size), false); | │ │ │ │ │ -| for (int i = merkle_first_leaf(piece_layer_size) | │ │ │ │ │ -| , end = i + num_pieces; i < end; ++i) | │ │ │ │ │ -| { | │ │ │ │ │ -| mask[std::size_t(i)] = true; | │ │ │ │ │ -| } | │ │ │ │ │ -| } | │ │ │ │ │ -| ti->free_piece_layers(); | │ │ │ │ │ -| } | │ │ │ │ │ -| atp.info_hashes = atp.ti->info_hashes(); | │ │ │ │ │ -| } | │ │ │ │ │ -|} | │ │ │ │ │ +| while (new_size < size) | │ │ │ │ │ +| new_size <<= 1; | │ │ │ │ │ | | │ │ │ │ │ -| add_torrent_params load_torrent_file(std::string const& filename) | │ │ │ │ │ -| { return load_torrent_file(filename, load_torrent_limits{}); } | │ │ │ │ │ -| add_torrent_params load_torrent_buffer(span buffer) | │ │ │ │ │ -| { return load_torrent_buffer(buffer, load_torrent_limits{}); } | │ │ │ │ │ -| add_torrent_params load_torrent_parsed(bdecode_node const& torrent_file) | │ │ │ │ │ -| { return load_torrent_parsed(torrent_file, load_torrent_limits{}); } | │ │ │ │ │ +| aux::unique_ptr new_storage(new packet_ptr[new_size]); | │ │ │ │ │ | | │ │ │ │ │ -|add_torrent_params load_torrent_file(std::string const& filename, load_torrent_limits const& cfg) | │ │ │ │ │ -|{ | │ │ │ │ │ -| add_torrent_params ret; | │ │ │ │ │ -| ret.ti = std::make_shared(filename, cfg); | │ │ │ │ │ -| update_atp(ret); | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ +| for (index_type i = m_first; i < (m_first + m_capacity); ++i) | │ │ │ │ │ +| new_storage[i & (new_size - 1)] = std::move(m_storage[i & (m_capacity - 1)]); | │ │ │ │ │ | | │ │ │ │ │ -| add_torrent_params load_torrent_buffer(span buffer, load_torrent_limits const& cfg) | │ │ │ │ │ -| { | │ │ │ │ │ -| add_torrent_params ret; | │ │ │ │ │ -| ret.ti = std::make_shared(buffer, cfg, from_span); | │ │ │ │ │ -| update_atp(ret); | │ │ │ │ │ -| return ret; | │ │ │ │ │ +| m_storage = std::move(new_storage); | │ │ │ │ │ +| m_capacity = new_size; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| add_torrent_params load_torrent_parsed(bdecode_node const& torrent_file, load_torrent_limits const& cfg) | │ │ │ │ │ +| packet_ptr packet_buffer::remove(index_type idx) | │ │ │ │ │ | { | │ │ │ │ │ -| add_torrent_params ret; | │ │ │ │ │ -| ret.ti = std::make_shared(torrent_file, cfg); | │ │ │ │ │ -| update_atp(ret); | │ │ │ │ │ -| return ret; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_._c_p_p_:|pre C++17, GCC and msvc does not make std::string nothrow move assignable, which means no type containing a string will be nothrow | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_7_8_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_m_o_v_e_ _a_s_s_i_g_n_a_b_l_e_ _b_y_ _d_e_f_a_u_l_t_ _e_i_t_h_e_r_ _s_t_a_t_i_c___a_s_s_e_r_t_(_s_t_d_:_:_i_s___n_o_t_h_r_o_w___m_o_v_e___a_s_s_i_g_n_a_b_l_e_:_:_v_a_l_u_e_ _,_ _"_s_h_o_u_l_d_ _b_e_ _n_o_t_h_r_o_w_ _m_o_v_e_ _a_s_s_i_g_n_a_b_l_e_"_)_;_ _ _ _ _ _ | │ │ │ │ │ -|********** pprree CC++++1177,, GGCCCC aanndd mmssvvcc ddooeess nnoott mmaakkee ssttdd::::ssttrriinngg nnootthhrrooww mmoovvee aassssiiggnnaabbllee,, wwhhiicchh mmeeaannss nnoo ttyyppee ccoonnttaaiinniinngg aa ssttrriinngg wwiillll bbee nnootthhrrooww mmoovvee aassssiiggnnaabbllee bbyy ddeeffaauulltt eeiitthheerr | │ │ │ │ │ -|ssttaattiicc__aasssseerrtt((ssttdd::::iiss__nnootthhrrooww__mmoovvee__aassssiiggnnaabbllee::::vvaalluuee ,, ""sshhoouulldd bbee nnootthhrrooww mmoovvee aassssiiggnnaabbllee""));; ********** | │ │ │ │ │ -|****** ....//ssrrcc//aadddd__ttoorrrreenntt__ppaarraammss..ccpppp::7788 ****** | │ │ │ │ │ -|DECL_FLAG(sequential_download); | │ │ │ │ │ -| DECL_FLAG(pinned); | │ │ │ │ │ -| DECL_FLAG(stop_when_ready); | │ │ │ │ │ -| DECL_FLAG(override_trackers); | │ │ │ │ │ -| DECL_FLAG(override_web_seeds); | │ │ │ │ │ -| DECL_FLAG(need_save_resume); | │ │ │ │ │ -| DECL_FLAG(override_resume_data); | │ │ │ │ │ -| DECL_FLAG(merge_resume_trackers); | │ │ │ │ │ -| DECL_FLAG(use_resume_save_path); | │ │ │ │ │ -| DECL_FLAG(merge_resume_http_seeds); | │ │ │ │ │ -| DECL_FLAG(default_flags); | │ │ │ │ │ -|#undef DECL_FLAG | │ │ │ │ │ -|#endif // TORRENT_ABI_VERSION | │ │ │ │ │ -| | │ │ │ │ │ -| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ -| , "should be nothrow move constructible"); | │ │ │ │ │ -| | │ │ │ │ │ -| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ -| , "should be nothrow move constructible"); | │ │ │ │ │ -| | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_a_d_d___t_o_r_r_e_n_t___p_a_r_a_m_s_._c_p_p_:|it would be nice if this was nothrow default constructible static_assert(std::is_nothrow_default_constructible::value , "should be | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_8_4_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_n_o_t_h_r_o_w_ _d_e_f_a_u_l_t_ _c_o_n_s_t_r_u_c_t_i_b_l_e_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee iiff tthhiiss wwaass nnootthhrrooww ddeeffaauulltt ccoonnssttrruuccttiibbllee ssttaattiicc__aasssseerrtt((ssttdd::::iiss__nnootthhrrooww__ddeeffaauulltt__ccoonnssttrruuccttiibbllee::::vvaalluuee ,, ""sshhoouulldd bbee nnootthhrrooww ddeeffaauulltt ccoonnssttrruuccttiibbllee""));; **********| │ │ │ │ │ -|****** ....//ssrrcc//aadddd__ttoorrrreenntt__ppaarraammss..ccpppp::8844 ****** | │ │ │ │ │ -|DECL_FLAG(pinned); | │ │ │ │ │ -| DECL_FLAG(stop_when_ready); | │ │ │ │ │ -| DECL_FLAG(override_trackers); | │ │ │ │ │ -| DECL_FLAG(override_web_seeds); | │ │ │ │ │ -| DECL_FLAG(need_save_resume); | │ │ │ │ │ -| DECL_FLAG(override_resume_data); | │ │ │ │ │ -| DECL_FLAG(merge_resume_trackers); | │ │ │ │ │ -| DECL_FLAG(use_resume_save_path); | │ │ │ │ │ -| DECL_FLAG(merge_resume_http_seeds); | │ │ │ │ │ -| DECL_FLAG(default_flags); | │ │ │ │ │ -|#undef DECL_FLAG | │ │ │ │ │ -|#endif // TORRENT_ABI_VERSION | │ │ │ │ │ -| | │ │ │ │ │ -| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ -| , "should be nothrow move constructible"); | │ │ │ │ │ -| | │ │ │ │ │ -| static_assert(std::is_nothrow_move_constructible::value | │ │ │ │ │ -| , "should be nothrow move constructible"); | │ │ │ │ │ +| INVARIANT_CHECK; | │ │ │ │ │ +|if (idx >= m_first + m_capacity) | │ │ │ │ │ +|return packet_ptr(); | │ │ │ │ │ | | │ │ │ │ │ +| if (compare_less_wrap(idx, m_first, 0xffff)) | │ │ │ │ │ +| return packet_ptr(); | │ │ │ │ │ | | │ │ │ │ │ +| std::size_t const mask = m_capacity - 1; | │ │ │ │ │ +| packet_ptr old_value = std::move(m_storage[idx & mask]); | │ │ │ │ │ +| m_storage[idx & mask].reset(); | │ │ │ │ │ | | │ │ │ │ │ -|namespace aux { | │ │ │ │ │ +| if (old_value) | │ │ │ │ │ +| { | │ │ │ │ │ +| --m_size; | │ │ │ │ │ +| if (m_size == 0) m_last = m_first; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| // returns whether this add_torrent_params object has "resume-data", i.e. | │ │ │ │ │ -| // information about which pieces we have. | │ │ │ │ │ -| bool contains_resume_data(add_torrent_params const& atp) | │ │ │ │ │ -| { | │ │ │ │ │ -| return !atp.have_pieces.empty() | │ │ │ │ │ -| || (atp.flags & torrent_flags::seed_mode); | │ │ │ │ │ -| } | │ │ │ │ │ -|} | │ │ │ │ │ +| if (idx == m_first && m_size != 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| ++m_first; | │ │ │ │ │ +| for (index_type i = 0; i < m_capacity; ++i, ++m_first) | │ │ │ │ │ +| if (m_storage[m_first & mask]) break; | │ │ │ │ │ +| m_first &= 0xffff; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| if (((idx + 1) & 0xffff) == m_last && m_size != 0) | │ │ │ │ │ +| { | │ │ │ │ │ +| --m_last; | │ │ │ │ │ +| for (index_type i = 0; i < m_capacity; ++i, --m_last) | │ │ │ │ │ +| if (m_storage[m_last & mask]) break; | │ │ │ │ │ +| ++m_last; | │ │ │ │ │ +|_ _ _ _m___l_a_s_t_ _&_=_ _0_x_f_f_f_f_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/_n_o_d_e_._c_p_p_:_1_1_7_7_ _|_k_e_e_p_ _t_h_e_ _r_e_t_u_r_n_e_d_ _v_a_l_u_e_ _t_o_ _p_a_s_s_ _a_s_ _a_ _l_i_m_i_t_ _t_o_ _w_r_i_t_e___n_o_d_e_s___e_n_t_r_i_e_s_ _w_h_e_n_ _i_m_p_l_e_m_e_n_t_e_d_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** kkeeeepp tthhee rreettuurrnneedd vvaalluuee ttoo ppaassss aass aa lliimmiitt ttoo wwrriittee__nnooddeess__eennttrriieess wwhheenn iimmpplleemmeenntteedd ********** | │ │ │ │ │ |****** ....//ssrrcc//kkaaddeemmlliiaa//nnooddee..ccpppp::11117777 ****** | │ │ │ │ │ |} | │ │ │ │ │ | } | │ │ │ │ │ | else if (query == "sample_infohashes") | │ │ │ │ │ | { | │ │ │ │ │ @@ -10618,14 +10618,161 @@ │ │ │ │ │ | std::vector const n = wanted_node->m_table.find_node(info_hash, {}); | │ │ │ │ │ | r[wanted_node->protocol_nodes_key()] = write_nodes_entry(n); | │ │ │ │ │ | } | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ |node::protocol_descriptor const& node::map_protocol_to_descriptor(udp const protocol) | │ │ │ │ │ |_{_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |This is temporary. For now, only report the largest routing table (of potentially multiple ones, for multi-homed systems) in next | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_2_8_9_ _ _ _ _ _ _ _ _ _|_m_a_j_o_r_ _v_e_r_s_i_o_n_,_ _b_r_e_a_k_ _t_h_e_ _A_B_I_ _a_n_d_ _s_u_p_p_o_r_t_ _r_e_p_o_r_t_i_n_g_ _a_l_l_ _o_f_ _t_h_e_m_ _i_n_ _t_h_e_ _d_h_t___s_t_a_t_s___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** TThhiiss iiss tteemmppoorraarryy.. FFoorr nnooww,, oonnllyy rreeppoorrtt tthhee llaarrggeesstt rroouuttiinngg ttaabbllee ((ooff ppootteennttiiaallllyy mmuullttiippllee oonneess,, ffoorr mmuullttii--hhoommeedd ssyysstteemmss)) iinn nneexxtt mmaajjoorr vveerrssiioonn,, bbrreeaakk tthhee AABBII aanndd | │ │ │ │ │ +|ssuuppppoorrtt rreeppoorrttiinngg aallll ooff tthheemm iinn tthhee ddhhtt__ssttaattss__aalleerrtt ********** | │ │ │ │ │ +|****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::228899 ****** | │ │ │ │ │ +|, m_bucket_size(bucket_size) | │ │ │ │ │ +|{ | │ │ │ │ │ +| // bucket sizes must be a power of 2 | │ │ │ │ │ +| TORRENT_ASSERT_VAL(((bucket_size - 1) & bucket_size) == 0, bucket_size); | │ │ │ │ │ +| TORRENT_UNUSED(log); | │ │ │ │ │ +| m_buckets.reserve(30); | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|int routing_table::bucket_limit(int bucket) const | │ │ │ │ │ +|{ | │ │ │ │ │ +| if (!m_settings.get_bool(settings_pack::dht_extended_routing_table)) return m_bucket_size; | │ │ │ │ │ +| | │ │ │ │ │ +| static const aux::array size_exceptions{{{16, 8, 4, 2}}}; | │ │ │ │ │ +| if (bucket < size_exceptions.end_index()) | │ │ │ │ │ +| return m_bucket_size * size_exceptions[bucket]; | │ │ │ │ │ +| return m_bucket_size; | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|void routing_table::status(std::vector& s) const | │ │ │ │ │ +|{ | │ │ │ │ │ +|if (s.size() > m_buckets.size()) return; | │ │ │ │ │ +|s.clear(); | │ │ │ │ │ +| for (auto const& i : m_buckets) | │ │ │ │ │ +| { | │ │ │ │ │ +| dht_routing_bucket b; | │ │ │ │ │ +| b.num_nodes = int(i.live_nodes.size()); | │ │ │ │ │ +| b.num_replacements = int(i.replacements.size()); | │ │ │ │ │ +| s.push_back(b); | │ │ │ │ │ +| } | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|_#_i_f_ _T_O_R_R_E_N_T___A_B_I___V_E_R_S_I_O_N_ _=_=_ _1_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |arvidn note when it's across IPv4 and IPv6, adding (dht_global_nodes) would make sense. in the future though, where we may have one | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_3_1_4_ _ _ _ _ _ _ _ _ _|_D_H_T_ _n_o_d_e_ _p_e_r_ _e_x_t_e_r_n_a_l_ _i_n_t_e_r_f_a_c_e_ _(_w_h_i_c_h_ _m_a_y_ _b_e_ _m_u_l_t_i_p_l_e_ _o_f_ _t_h_e_ _s_a_m_e_ _a_d_d_r_e_s_s_ _f_a_m_i_l_y_)_,_ _t_h_e_n_ _i_t_ _b_e_c_o_m_e_s_ _a_ _b_i_t_ _t_r_i_c_k_i_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** aarrvviiddnn nnoottee wwhheenn iitt''ss aaccrroossss IIPPvv44 aanndd IIPPvv66,, aaddddiinngg ((ddhhtt__gglloobbaall__nnooddeess)) wwoouulldd mmaakkee sseennssee.. iinn tthhee ffuuttuurree tthhoouugghh,, wwhheerree wwee mmaayy hhaavvee oonnee DDHHTT nnooddee ppeerr eexxtteerrnnaall iinntteerrffaaccee | │ │ │ │ │ +|((wwhhiicchh mmaayy bbee mmuullttiippllee ooff tthhee ssaammee aaddddrreessss ffaammiillyy)),, tthheenn iitt bbeeccoommeess aa bbiitt ttrriicckkiieerr ********** | │ │ │ │ │ +|****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::331144 ****** | │ │ │ │ │ +|if (s.size() > m_buckets.size()) return; | │ │ │ │ │ +| s.clear(); | │ │ │ │ │ +| for (auto const& i : m_buckets) | │ │ │ │ │ +| { | │ │ │ │ │ +| dht_routing_bucket b; | │ │ │ │ │ +| b.num_nodes = int(i.live_nodes.size()); | │ │ │ │ │ +| b.num_replacements = int(i.replacements.size()); | │ │ │ │ │ +| s.push_back(b); | │ │ │ │ │ +| } | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +|void routing_table::status(session_status& s) const | │ │ │ │ │ +|{ | │ │ │ │ │ +| int dht_nodes; | │ │ │ │ │ +| int dht_node_cache; | │ │ │ │ │ +| int ignore; | │ │ │ │ │ +| std::tie(dht_nodes, dht_node_cache, ignore) = size(); | │ │ │ │ │ +| s.dht_nodes += dht_nodes; | │ │ │ │ │ +| s.dht_node_cache += dht_node_cache; | │ │ │ │ │ +|s.dht_global_nodes += num_global_nodes(); | │ │ │ │ │ +| | │ │ │ │ │ +| for (auto const& i : m_buckets) | │ │ │ │ │ +| { | │ │ │ │ │ +| dht_routing_bucket b; | │ │ │ │ │ +| b.num_nodes = int(i.live_nodes.size()); | │ │ │ │ │ +| b.num_replacements = int(i.replacements.size()); | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| b.last_active = 0; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| s.dht_routing_table.push_back(b); | │ │ │ │ │ +| } | │ │ │ │ │ +|} | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|std::tuple routing_table::size() const | │ │ │ │ │ +|{ | │ │ │ │ │ +| int nodes = 0; | │ │ │ │ │ +| int replacements = 0; | │ │ │ │ │ +| int confirmed = 0; | │ │ │ │ │ +| for (auto const& i : m_buckets) | │ │ │ │ │ +| { | │ │ │ │ │ +| nodes += int(i.live_nodes.size()); | │ │ │ │ │ +| confirmed += static_cast(std::count_if(i.live_nodes.begin(), i.live_nodes.end() | │ │ │ │ │ +| , [](node_entry const& k) { return k.confirmed(); } )); | │ │ │ │ │ +| | │ │ │ │ │ +| replacements += int(i.replacements.size()); | │ │ │ │ │ +| } | │ │ │ │ │ +| return std::make_tuple(nodes, replacements, confirmed); | │ │ │ │ │ +|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |this need to take bucket "prefix" into account. It should be unified with add_node_impl() | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_5_1_8_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** tthhiiss nneeeedd ttoo ttaakkee bbuucckkeett ""pprreeffiixx"" iinnttoo aaccccoouunntt.. IItt sshhoouulldd bbee uunniiffiieedd wwiitthh aadddd__nnooddee__iimmppll(()) ********** | │ │ │ │ │ +|****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::551188 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| for (auto i = m_buckets.begin() , end(m_buckets.end()); i != end; ++i) | │ │ │ │ │ +| { | │ │ │ │ │ +| for (auto j = i->replacements.begin(); j != i->replacements.end(); ++j) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (j->addr() != ep.address()) continue; | │ │ │ │ │ +| if (j->port() != ep.port()) continue; | │ │ │ │ │ +| return std::make_tuple(&*j, i, &i->replacements); | │ │ │ │ │ +| } | │ │ │ │ │ +| for (auto j = i->live_nodes.begin(); j != i->live_nodes.end(); ++j) | │ │ │ │ │ +| { | │ │ │ │ │ +| if (j->addr() != ep.address()) continue; | │ │ │ │ │ +| if (j->port() != ep.port()) continue; | │ │ │ │ │ +| return std::make_tuple(&*j, i, &i->live_nodes); | │ │ │ │ │ +| } | │ │ │ │ │ +| } | │ │ │ │ │ +| return std::tuple | │ │ │ │ │ +| {nullptr, m_buckets.end(), nullptr}; | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|void routing_table::fill_from_replacements(table_t::iterator bucket) | │ │ │ │ │ +|{ | │ │ │ │ │ +| bucket_t& b = bucket->live_nodes; | │ │ │ │ │ +| bucket_t& rb = bucket->replacements; | │ │ │ │ │ +| int const bucket_size = bucket_limit(int(std::distance(m_buckets.begin(), bucket))); | │ │ │ │ │ +| | │ │ │ │ │ +| if (int(b.size()) >= bucket_size) return; | │ │ │ │ │ +| | │ │ │ │ │ +| // sort by RTT first, to find the node with the lowest | │ │ │ │ │ +| // RTT that is pinged | │ │ │ │ │ +| std::sort(rb.begin(), rb.end()); | │ │ │ │ │ +| | │ │ │ │ │ +| while (int(b.size()) < bucket_size && !rb.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| auto j = std::find_if(rb.begin(), rb.end(), std::bind(&node_entry::pinged, _1)); | │ │ │ │ │ +| if (j == rb.end()) break; | │ │ │ │ │ +| b.push_back(*j); | │ │ │ │ │ +| rb.erase(j); | │ │ │ │ │ +| } | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|void routing_table::prune_empty_bucket() | │ │ │ │ │ +|{ | │ │ │ │ │ +| if (m_buckets.back().live_nodes.empty() | │ │ │ │ │ +| && m_buckets.back().replacements.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| m_buckets.erase(m_buckets.end() - 1); | │ │ │ │ │ +| } | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|_v_o_i_d_ _r_o_u_t_i_n_g___t_a_b_l_e_:_:_r_e_m_o_v_e___n_o_d_e_(_n_o_d_e___e_n_t_r_y_*_ _n_,_ _b_u_c_k_e_t___t_*_ _b_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/_p_u_t___d_a_t_a_._c_p_p_: |what if o is not an instance of put_data_observer? This need to be redesigned for better type safety. | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_9_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** wwhhaatt iiff oo iiss nnoott aann iinnssttaannccee ooff ppuutt__ddaattaa__oobbsseerrvveerr?? TThhiiss nneeeedd ttoo bbee rreeddeessiiggnneedd ffoorr bbeetttteerr ttyyppee ssaaffeettyy.. ********** | │ │ │ │ │ |****** ....//ssrrcc//kkaaddeemmlliiaa//ppuutt__ddaattaa..ccpppp::9922 ****** | │ │ │ │ │ |} | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ @@ -10722,68 +10869,14 @@ │ │ │ │ │ | | │ │ │ │ │ | address_v4::bytes_type b4{}; | │ │ │ │ │ | address_v6::bytes_type b6{}; | │ │ │ │ │ | if (ip_.is_v6()) | │ │ │ │ │ | { | │ │ │ │ │ | b6 = ip_.to_v6().to_bytes(); | │ │ │ │ │ |_ _ _i_p_ _=_ _b_6_._d_a_t_a_(_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |pick the closest node rather than the first | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_d_h_t___t_r_a_c_k_e_r_._c_p_p_:_3_1_7_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ppiicckk tthhee cclloosseesstt nnooddee rraatthheerr tthhaann tthhee ffiirrsstt ********** | │ │ │ │ │ -|****** ....//ssrrcc//kkaaddeemmlliiaa//ddhhtt__ttrraacckkeerr..ccpppp::331177 ****** | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ -| m_log->log(dht_logger::tracker, "*** new write key*** %d nodes" | │ │ │ │ │ -| , int(m_nodes.size())); | │ │ │ │ │ -|#endif | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void dht_tracker::update_storage_node_ids() | │ │ │ │ │ -| { | │ │ │ │ │ -| std::vector ids; | │ │ │ │ │ -| for (auto& n : m_nodes) | │ │ │ │ │ -| ids.push_back(n.second.dht.nid()); | │ │ │ │ │ -| m_storage.update_node_ids(ids); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| node* dht_tracker::get_node(node_id const& id, std::string const& family_name) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_UNUSED(id); | │ │ │ │ │ -| for (auto& n : m_nodes) | │ │ │ │ │ -| { | │ │ │ │ │ -|if (n.second.dht.protocol_family_name() == family_name) | │ │ │ │ │ -|return &n.second.dht; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| return nullptr; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void dht_tracker::get_peers(sha1_hash const& ih | │ │ │ │ │ -| , std::function const&)> f) | │ │ │ │ │ -| { | │ │ │ │ │ -| for (auto& n : m_nodes) | │ │ │ │ │ -| n.second.dht.get_peers(ih, f, {}, {}); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void dht_tracker::announce(sha1_hash const& ih, int listen_port | │ │ │ │ │ -| , announce_flags_t const flags | │ │ │ │ │ -| , std::function const&)> f) | │ │ │ │ │ -| { | │ │ │ │ │ -| for (auto& n : m_nodes) | │ │ │ │ │ -| n.second.dht.announce(ih, listen_port, flags, f); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| void dht_tracker::sample_infohashes(udp::endpoint const& ep, sha1_hash const& target | │ │ │ │ │ -| , std::function | │ │ │ │ │ -| , std::vector>)> f) | │ │ │ │ │ -| { | │ │ │ │ │ -| for (auto& n : m_nodes) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _ _i_f_ _(_e_p_._p_r_o_t_o_c_o_l_(_)_ _!_=_ _(_n_._f_i_r_s_t_._g_e_t___e_x_t_e_r_n_a_l___a_d_d_r_e_s_s_(_)_._i_s___v_4_(_)_ _?_ _u_d_p_:_:_v_4_(_)_ _:_ _u_d_p_:_:_v_6_(_)_)_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |_r_e_l_e_v_a_n_c_e_ _0_|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/_i_t_e_m_._c_p_p_:_1_4_3_ _ _|_i_m_p_l_e_m_e_n_t_ _c_t_o_r_ _f_o_r_ _e_n_t_r_y_ _f_r_o_m_ _b_d_e_c_o_d_e___n_o_d_e_?_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** iimmpplleemmeenntt ccttoorr ffoorr eennttrryy ffrroomm bbddeeccooddee__nnooddee?? ********** | │ │ │ │ │ |****** ....//ssrrcc//kkaaddeemmlliiaa//iitteemm..ccpppp::114433 ****** | │ │ │ │ │ |, secret_key const& sk) | │ │ │ │ │ |{ | │ │ │ │ │ | char str[1200]; | │ │ │ │ │ | int const len = canonical_string(v, seq, salt, str); | │ │ │ │ │ @@ -10830,161 +10923,68 @@ │ │ │ │ │ | m_pk = pk; | │ │ │ │ │ | m_seq = seq; | │ │ │ │ │ | m_mutable = true; | │ │ │ │ │ | m_value = std::move(v); | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ |_v_o_i_d_ _i_t_e_m_:_:_a_s_s_i_g_n_(_b_d_e_c_o_d_e___n_o_d_e_ _c_o_n_s_t_&_ _v_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |This is temporary. For now, only report the largest routing table (of potentially multiple ones, for multi-homed systems) in next | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_2_8_9_ _ _ _ _ _ _ _ _ _|_m_a_j_o_r_ _v_e_r_s_i_o_n_,_ _b_r_e_a_k_ _t_h_e_ _A_B_I_ _a_n_d_ _s_u_p_p_o_r_t_ _r_e_p_o_r_t_i_n_g_ _a_l_l_ _o_f_ _t_h_e_m_ _i_n_ _t_h_e_ _d_h_t___s_t_a_t_s___a_l_e_r_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** TThhiiss iiss tteemmppoorraarryy.. FFoorr nnooww,, oonnllyy rreeppoorrtt tthhee llaarrggeesstt rroouuttiinngg ttaabbllee ((ooff ppootteennttiiaallllyy mmuullttiippllee oonneess,, ffoorr mmuullttii--hhoommeedd ssyysstteemmss)) iinn nneexxtt mmaajjoorr vveerrssiioonn,, bbrreeaakk tthhee AABBII aanndd | │ │ │ │ │ -|ssuuppppoorrtt rreeppoorrttiinngg aallll ooff tthheemm iinn tthhee ddhhtt__ssttaattss__aalleerrtt ********** | │ │ │ │ │ -|****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::228899 ****** | │ │ │ │ │ -|, m_bucket_size(bucket_size) | │ │ │ │ │ -|{ | │ │ │ │ │ -| // bucket sizes must be a power of 2 | │ │ │ │ │ -| TORRENT_ASSERT_VAL(((bucket_size - 1) & bucket_size) == 0, bucket_size); | │ │ │ │ │ -| TORRENT_UNUSED(log); | │ │ │ │ │ -| m_buckets.reserve(30); | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|int routing_table::bucket_limit(int bucket) const | │ │ │ │ │ -|{ | │ │ │ │ │ -| if (!m_settings.get_bool(settings_pack::dht_extended_routing_table)) return m_bucket_size; | │ │ │ │ │ -| | │ │ │ │ │ -| static const aux::array size_exceptions{{{16, 8, 4, 2}}}; | │ │ │ │ │ -| if (bucket < size_exceptions.end_index()) | │ │ │ │ │ -| return m_bucket_size * size_exceptions[bucket]; | │ │ │ │ │ -| return m_bucket_size; | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void routing_table::status(std::vector& s) const | │ │ │ │ │ -|{ | │ │ │ │ │ -|if (s.size() > m_buckets.size()) return; | │ │ │ │ │ -|s.clear(); | │ │ │ │ │ -| for (auto const& i : m_buckets) | │ │ │ │ │ -| { | │ │ │ │ │ -| dht_routing_bucket b; | │ │ │ │ │ -| b.num_nodes = int(i.live_nodes.size()); | │ │ │ │ │ -| b.num_replacements = int(i.replacements.size()); | │ │ │ │ │ -| s.push_back(b); | │ │ │ │ │ -| } | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|_#_i_f_ _T_O_R_R_E_N_T___A_B_I___V_E_R_S_I_O_N_ _=_=_ _1_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |arvidn note when it's across IPv4 and IPv6, adding (dht_global_nodes) would make sense. in the future though, where we may have one | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_3_1_4_ _ _ _ _ _ _ _ _ _|_D_H_T_ _n_o_d_e_ _p_e_r_ _e_x_t_e_r_n_a_l_ _i_n_t_e_r_f_a_c_e_ _(_w_h_i_c_h_ _m_a_y_ _b_e_ _m_u_l_t_i_p_l_e_ _o_f_ _t_h_e_ _s_a_m_e_ _a_d_d_r_e_s_s_ _f_a_m_i_l_y_)_,_ _t_h_e_n_ _i_t_ _b_e_c_o_m_e_s_ _a_ _b_i_t_ _t_r_i_c_k_i_e_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** aarrvviiddnn nnoottee wwhheenn iitt''ss aaccrroossss IIPPvv44 aanndd IIPPvv66,, aaddddiinngg ((ddhhtt__gglloobbaall__nnooddeess)) wwoouulldd mmaakkee sseennssee.. iinn tthhee ffuuttuurree tthhoouugghh,, wwhheerree wwee mmaayy hhaavvee oonnee DDHHTT nnooddee ppeerr eexxtteerrnnaall iinntteerrffaaccee | │ │ │ │ │ -|((wwhhiicchh mmaayy bbee mmuullttiippllee ooff tthhee ssaammee aaddddrreessss ffaammiillyy)),, tthheenn iitt bbeeccoommeess aa bbiitt ttrriicckkiieerr ********** | │ │ │ │ │ -|****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::331144 ****** | │ │ │ │ │ -|if (s.size() > m_buckets.size()) return; | │ │ │ │ │ -| s.clear(); | │ │ │ │ │ -| for (auto const& i : m_buckets) | │ │ │ │ │ -| { | │ │ │ │ │ -| dht_routing_bucket b; | │ │ │ │ │ -| b.num_nodes = int(i.live_nodes.size()); | │ │ │ │ │ -| b.num_replacements = int(i.replacements.size()); | │ │ │ │ │ -| s.push_back(b); | │ │ │ │ │ -| } | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -|void routing_table::status(session_status& s) const | │ │ │ │ │ -|{ | │ │ │ │ │ -| int dht_nodes; | │ │ │ │ │ -| int dht_node_cache; | │ │ │ │ │ -| int ignore; | │ │ │ │ │ -| std::tie(dht_nodes, dht_node_cache, ignore) = size(); | │ │ │ │ │ -| s.dht_nodes += dht_nodes; | │ │ │ │ │ -| s.dht_node_cache += dht_node_cache; | │ │ │ │ │ -|s.dht_global_nodes += num_global_nodes(); | │ │ │ │ │ -| | │ │ │ │ │ -| for (auto const& i : m_buckets) | │ │ │ │ │ -| { | │ │ │ │ │ -| dht_routing_bucket b; | │ │ │ │ │ -| b.num_nodes = int(i.live_nodes.size()); | │ │ │ │ │ -| b.num_replacements = int(i.replacements.size()); | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| b.last_active = 0; | │ │ │ │ │ +|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |pick the closest node rather than the first | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_d_h_t___t_r_a_c_k_e_r_._c_p_p_:_3_1_7_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ppiicckk tthhee cclloosseesstt nnooddee rraatthheerr tthhaann tthhee ffiirrsstt ********** | │ │ │ │ │ +|****** ....//ssrrcc//kkaaddeemmlliiaa//ddhhtt__ttrraacckkeerr..ccpppp::331177 ****** | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ +| m_log->log(dht_logger::tracker, "*** new write key*** %d nodes" | │ │ │ │ │ +| , int(m_nodes.size())); | │ │ │ │ │ |#endif | │ │ │ │ │ -| s.dht_routing_table.push_back(b); | │ │ │ │ │ | } | │ │ │ │ │ -|} | │ │ │ │ │ -|#endif | │ │ │ │ │ | | │ │ │ │ │ -|std::tuple routing_table::size() const | │ │ │ │ │ -|{ | │ │ │ │ │ -| int nodes = 0; | │ │ │ │ │ -| int replacements = 0; | │ │ │ │ │ -| int confirmed = 0; | │ │ │ │ │ -| for (auto const& i : m_buckets) | │ │ │ │ │ +| void dht_tracker::update_storage_node_ids() | │ │ │ │ │ | { | │ │ │ │ │ -| nodes += int(i.live_nodes.size()); | │ │ │ │ │ -| confirmed += static_cast(std::count_if(i.live_nodes.begin(), i.live_nodes.end() | │ │ │ │ │ -| , [](node_entry const& k) { return k.confirmed(); } )); | │ │ │ │ │ -| | │ │ │ │ │ -| replacements += int(i.replacements.size()); | │ │ │ │ │ +| std::vector ids; | │ │ │ │ │ +| for (auto& n : m_nodes) | │ │ │ │ │ +| ids.push_back(n.second.dht.nid()); | │ │ │ │ │ +| m_storage.update_node_ids(ids); | │ │ │ │ │ | } | │ │ │ │ │ -| return std::make_tuple(nodes, replacements, confirmed); | │ │ │ │ │ -|_}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_s_r_c_/_k_a_d_e_m_l_i_a_/ |this need to take bucket "prefix" into account. It should be unified with add_node_impl() | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_r_o_u_t_i_n_g___t_a_b_l_e_._c_p_p_:_5_1_8_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** tthhiiss nneeeedd ttoo ttaakkee bbuucckkeett ""pprreeffiixx"" iinnttoo aaccccoouunntt.. IItt sshhoouulldd bbee uunniiffiieedd wwiitthh aadddd__nnooddee__iimmppll(()) ********** | │ │ │ │ │ -|****** ....//ssrrcc//kkaaddeemmlliiaa//rroouuttiinngg__ttaabbllee..ccpppp::551188 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| for (auto i = m_buckets.begin() , end(m_buckets.end()); i != end; ++i) | │ │ │ │ │ +| | │ │ │ │ │ +| node* dht_tracker::get_node(node_id const& id, std::string const& family_name) | │ │ │ │ │ | { | │ │ │ │ │ -| for (auto j = i->replacements.begin(); j != i->replacements.end(); ++j) | │ │ │ │ │ -| { | │ │ │ │ │ -| if (j->addr() != ep.address()) continue; | │ │ │ │ │ -| if (j->port() != ep.port()) continue; | │ │ │ │ │ -| return std::make_tuple(&*j, i, &i->replacements); | │ │ │ │ │ -| } | │ │ │ │ │ -| for (auto j = i->live_nodes.begin(); j != i->live_nodes.end(); ++j) | │ │ │ │ │ +| TORRENT_UNUSED(id); | │ │ │ │ │ +| for (auto& n : m_nodes) | │ │ │ │ │ | { | │ │ │ │ │ -| if (j->addr() != ep.address()) continue; | │ │ │ │ │ -| if (j->port() != ep.port()) continue; | │ │ │ │ │ -| return std::make_tuple(&*j, i, &i->live_nodes); | │ │ │ │ │ +|if (n.second.dht.protocol_family_name() == family_name) | │ │ │ │ │ +|return &n.second.dht; | │ │ │ │ │ | } | │ │ │ │ │ -| } | │ │ │ │ │ -| return std::tuple | │ │ │ │ │ -| {nullptr, m_buckets.end(), nullptr}; | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|void routing_table::fill_from_replacements(table_t::iterator bucket) | │ │ │ │ │ -|{ | │ │ │ │ │ -| bucket_t& b = bucket->live_nodes; | │ │ │ │ │ -| bucket_t& rb = bucket->replacements; | │ │ │ │ │ -| int const bucket_size = bucket_limit(int(std::distance(m_buckets.begin(), bucket))); | │ │ │ │ │ -| | │ │ │ │ │ -| if (int(b.size()) >= bucket_size) return; | │ │ │ │ │ | | │ │ │ │ │ -| // sort by RTT first, to find the node with the lowest | │ │ │ │ │ -| // RTT that is pinged | │ │ │ │ │ -| std::sort(rb.begin(), rb.end()); | │ │ │ │ │ +| return nullptr; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| while (int(b.size()) < bucket_size && !rb.empty()) | │ │ │ │ │ +| void dht_tracker::get_peers(sha1_hash const& ih | │ │ │ │ │ +| , std::function const&)> f) | │ │ │ │ │ | { | │ │ │ │ │ -| auto j = std::find_if(rb.begin(), rb.end(), std::bind(&node_entry::pinged, _1)); | │ │ │ │ │ -| if (j == rb.end()) break; | │ │ │ │ │ -| b.push_back(*j); | │ │ │ │ │ -| rb.erase(j); | │ │ │ │ │ +| for (auto& n : m_nodes) | │ │ │ │ │ +| n.second.dht.get_peers(ih, f, {}, {}); | │ │ │ │ │ | } | │ │ │ │ │ -|} | │ │ │ │ │ | | │ │ │ │ │ -|void routing_table::prune_empty_bucket() | │ │ │ │ │ -|{ | │ │ │ │ │ -| if (m_buckets.back().live_nodes.empty() | │ │ │ │ │ -| && m_buckets.back().replacements.empty()) | │ │ │ │ │ +| void dht_tracker::announce(sha1_hash const& ih, int listen_port | │ │ │ │ │ +| , announce_flags_t const flags | │ │ │ │ │ +| , std::function const&)> f) | │ │ │ │ │ | { | │ │ │ │ │ -| m_buckets.erase(m_buckets.end() - 1); | │ │ │ │ │ +| for (auto& n : m_nodes) | │ │ │ │ │ +| n.second.dht.announce(ih, listen_port, flags, f); | │ │ │ │ │ | } | │ │ │ │ │ -|} | │ │ │ │ │ | | │ │ │ │ │ -|_v_o_i_d_ _r_o_u_t_i_n_g___t_a_b_l_e_:_:_r_e_m_o_v_e___n_o_d_e_(_n_o_d_e___e_n_t_r_y_*_ _n_,_ _b_u_c_k_e_t___t_*_ _b_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| void dht_tracker::sample_infohashes(udp::endpoint const& ep, sha1_hash const& target | │ │ │ │ │ +| , std::function | │ │ │ │ │ +| , std::vector>)> f) | │ │ │ │ │ +| { | │ │ │ │ │ +| for (auto& n : m_nodes) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _ _i_f_ _(_e_p_._p_r_o_t_o_c_o_l_(_)_ _!_=_ _(_n_._f_i_r_s_t_._g_e_t___e_x_t_e_r_n_a_l___a_d_d_r_e_s_s_(_)_._i_s___v_4_(_)_ _?_ _u_d_p_:_:_v_4_(_)_ _:_ _u_d_p_:_:_v_6_(_)_)_)_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |change the type to std::shared_ptr in C++17 it is used as if immutable, it cannot be const for technical reasons right now. | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_t_o_r_r_e_n_t___i_n_f_o_._h_p_p_:_7_2_9_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** cchhaannggee tthhee ttyyppee ttoo ssttdd::::sshhaarreedd__ppttrr iinn CC++++1177 iitt iiss uusseedd aass iiff iimmmmuuttaabbllee,, iitt ccaannnnoott bbee ccoonnsstt ffoorr tteecchhnniiccaall rreeaassoonnss rriigghhtt nnooww.. ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ttoorrrreenntt__iinnffoo..hhpppp::772299 ****** | │ │ │ │ │ | // these are the collections from outside of the info-dict. These are | │ │ │ │ │ | // owning strings, since we only keep the info-section around, these | │ │ │ │ │ | // cannot be pointers into that buffer. | │ │ │ │ │ @@ -11031,152 +11031,121 @@ │ │ │ │ │ | std::int32_t m_piece_hashes = 0; | │ │ │ │ │ | | │ │ │ │ │ | // the number of bytes in m_info_section | │ │ │ │ │ | std::int32_t m_info_section_size = 0; | │ │ │ │ │ | | │ │ │ │ │ | // this is used when creating a torrent. If there's | │ │ │ │ │ |_ _ _/_/_ _o_n_l_y_ _o_n_e_ _f_i_l_e_ _t_h_e_r_e_ _a_r_e_ _c_a_s_e_s_ _w_h_e_r_e_ _i_t_'_s_ _i_m_p_o_s_s_i_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |hide this declaration when deprecated functions are disabled, and remove its internal use | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_i_d_e_n_t_i_f_y___c_l_i_e_n_t_._h_p_p_:_4_8_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** hhiiddee tthhiiss ddeeccllaarraattiioonn wwhheenn ddeepprreeccaatteedd ffuunnccttiioonnss aarree ddiissaabblleedd,, aanndd rreemmoovvee iittss iinntteerrnnaall uussee ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//iiddeennttiiffyy__cclliieenntt..hhpppp::4488 ****** | │ │ │ │ │ -|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ -|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ -|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ -| | │ │ │ │ │ -|*/ | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED | │ │ │ │ │ -|#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |should this be allocated lazily? | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_i_e_c_e___p_i_c_k_e_r_._h_p_p_:_8_2_3_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** sshhoouulldd tthhiiss bbee aallllooccaatteedd llaazziillyy?? ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppiieeccee__ppiicckkeerr..hhpppp::882233 ****** | │ │ │ │ │ +|// download list it may live in now | │ │ │ │ │ +| std::vector::iterator update_piece_state( | │ │ │ │ │ +| std::vector::iterator dp); | │ │ │ │ │ | | │ │ │ │ │ -|#include "libtorrent/config.hpp" | │ │ │ │ │ +| private: | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ +|#if TORRENT_USE_ASSERTS || TORRENT_USE_INVARIANT_CHECKS | │ │ │ │ │ +| index_range categories() const | │ │ │ │ │ +| { return {{}, piece_picker::piece_pos::num_download_categories}; } | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -|#include "libtorrent/peer_id.hpp" | │ │ │ │ │ -|#include "libtorrent/fingerprint.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ -| | │ │ │ │ │ -|namespace aux { | │ │ │ │ │ -| | │ │ │ │ │ -| TORRENT_EXTRA_EXPORT | │ │ │ │ │ -| std::string identify_client_impl(const peer_id& p); | │ │ │ │ │ -| | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -| // these functions don't really need to be public. This mechanism of | │ │ │ │ │ -| // advertising client software and version is also out-dated. | │ │ │ │ │ -| | │ │ │ │ │ -| // This function can can be used to extract a string describing a client | │ │ │ │ │ -| // version from its peer-id. It will recognize most clients that have this | │ │ │ │ │ -| // kind of identification in the peer-id. | │ │ │ │ │ -| TORRENT_DEPRECATED_EXPORT | │ │ │ │ │ -| std::string identify_client(const peer_id& p); | │ │ │ │ │ +| // the following vectors are mutable because they sometimes may | │ │ │ │ │ +| // be updated lazily, triggered by const functions | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| // this maps indices to number of peers that has this piece and | │ │ │ │ │ +| // index into the m_piece_info vectors. | │ │ │ │ │ +| // piece_pos::we_have_index means that we have the piece, so it | │ │ │ │ │ +| // doesn't exist in the piece_info buckets | │ │ │ │ │ +| // pieces with the filtered flag set doesn't have entries in | │ │ │ │ │ +| // the m_piece_info buckets either | │ │ │ │ │ +|mutable aux::vector m_piece_map; | │ │ │ │ │ | | │ │ │ │ │ -|#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" | │ │ │ │ │ +| // tracks the number of bytes in a specific piece that are part of a pad | │ │ │ │ │ +| // file. The padding is assumed to be at the end of the piece, and the | │ │ │ │ │ +| // blocks covered by the pad bytes are not picked by the piece picker | │ │ │ │ │ +| std::unordered_map m_pads_in_piece; | │ │ │ │ │ | | │ │ │ │ │ -| // Returns an optional fingerprint if any can be identified from the peer | │ │ │ │ │ -| // id. This can be used to automate the identification of clients. It will | │ │ │ │ │ -| // not be able to identify peers with non- standard encodings. Only Azureus | │ │ │ │ │ -| // style, Shadow's style and Mainline style. | │ │ │ │ │ -| TORRENT_DEPRECATED_EXPORT | │ │ │ │ │ -| boost::optional | │ │ │ │ │ -| client_fingerprint(peer_id const& p); | │ │ │ │ │ +| // when the adjacent_piece affinity is enabled, this contains the most | │ │ │ │ │ +| // recent "extents" of adjacent pieces that have been requested from | │ │ │ │ │ +| // this is mutable because it's updated by functions to pick pieces, which | │ │ │ │ │ +| // are const. That's an efficient place to update it, since it's being | │ │ │ │ │ +| // traversed already. | │ │ │ │ │ +| mutable std::vector m_recent_extents; | │ │ │ │ │ | | │ │ │ │ │ -|_#_i_n_c_l_u_d_e_ _"_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/_d_i_s_a_b_l_e___w_a_r_n_i_n_g_s___p_o_p_._h_p_p_"_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |move to aux | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_o_c_k_e_t___t_y_p_e_._h_p_p_:_6_0_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmoovvee ttoo aauuxx ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssoocckkeett__ttyyppee..hhpppp::6600 ****** | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ +| // the number of bytes of pad file set in this piece picker | │ │ │ │ │ +| std::int64_t m_num_pad_bytes = 0; | │ │ │ │ │ | | │ │ │ │ │ -|// A type describing kinds of sockets involved in various operations or events. | │ │ │ │ │ -|enum class socket_type_t : std::uint8_t { | │ │ │ │ │ -| tcp, | │ │ │ │ │ -| socks5, | │ │ │ │ │ -| http, | │ │ │ │ │ -| utp, | │ │ │ │ │ -| i2p, | │ │ │ │ │ -| tcp_ssl, | │ │ │ │ │ -| socks5_ssl, | │ │ │ │ │ -| http_ssl, | │ │ │ │ │ -| utp_ssl, | │ │ │ │ │ +| // the number of pad blocks that we already have | │ │ │ │ │ +| std::int64_t m_have_pad_bytes = 0; | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_ABI_VERSION <= 2 | │ │ │ │ │ -| udp TORRENT_DEPRECATED_ENUM = utp, | │ │ │ │ │ -|#endif | │ │ │ │ │ -|}; | │ │ │ │ │ +| // the number of pad blocks part of filtered pieces we don't have | │ │ │ │ │ +| std::int64_t m_filtered_pad_bytes = 0; | │ │ │ │ │ | | │ │ │ │ │ -|// return a short human readable name for types of socket | │ │ │ │ │ -|char const* socket_type_name(socket_type_t); | │ │ │ │ │ +| // the number of pad blocks we have that are also filtered | │ │ │ │ │ +| std::int64_t m_have_filtered_pad_bytes = 0; | │ │ │ │ │ | | │ │ │ │ │ -|} | │ │ │ │ │ +| // the number of seeds. These are not added to | │ │ │ │ │ +| // the availability counters of the pieces | │ │ │ │ │ +| int m_seeds = 0; | │ │ │ │ │ | | │ │ │ │ │ -|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |include the number of peers received from this tracker, at last announce | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_a_n_n_o_u_n_c_e___e_n_t_r_y_._h_p_p_:_7_6_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinncclluuddee tthhee nnuummbbeerr ooff ppeeeerrss rreecceeiivveedd ffrroomm tthhiiss ttrraacckkeerr,, aatt llaasstt aannnnoouunnccee ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aannnnoouunnccee__eennttrryy..hhpppp::7766 ****** | │ │ │ │ │ -| struct TORRENT_EXPORT announce_infohash | │ │ │ │ │ -| { | │ │ │ │ │ -| // internal | │ │ │ │ │ -| TORRENT_UNEXPORT announce_infohash(); | │ │ │ │ │ +|_ _ _/_/_ _t_h_i_s_ _v_e_c_t_o_r_ _c_o_n_t_a_i_n_s_ _a_l_l_ _p_i_e_c_e_ _i_n_d_i_c_e_s_ _t_h_a_t_ _a_r_e_ _p_i_c_k_a_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |it would be more intuitive to account "wanted" pieces instead of filtered | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_i_e_c_e___p_i_c_k_e_r_._h_p_p_:_8_9_5_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee mmoorree iinnttuuiittiivvee ttoo aaccccoouunntt ""wwaanntteedd"" ppiieecceess iinnsstteeaadd ooff ffiilltteerreedd ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppiieeccee__ppiicckkeerr..hhpppp::889955 ****** | │ │ │ │ │ +| // this holds the information of the blocks in partially downloaded | │ │ │ │ │ +| // pieces. the downloading_piece::info index point into this vector for | │ │ │ │ │ +| // its storage | │ │ │ │ │ +| aux::vector m_block_info; | │ │ │ │ │ | | │ │ │ │ │ -| // if this tracker has returned an error or warning message | │ │ │ │ │ -| // that message is stored here | │ │ │ │ │ -| std::string message; | │ │ │ │ │ +| // these are block ranges in m_block_info that are free. The numbers | │ │ │ │ │ +| // in here, when multiplied by blocks_per_piece is the index to the | │ │ │ │ │ +| // first block in the range that's free to use by a new downloading_piece. | │ │ │ │ │ +| // this is a free-list. | │ │ │ │ │ +| std::vector m_free_block_infos; | │ │ │ │ │ | | │ │ │ │ │ -| // if this tracker failed the last time it was contacted | │ │ │ │ │ -| // this error code specifies what error occurred | │ │ │ │ │ -| error_code last_error; | │ │ │ │ │ +| std::uint16_t m_blocks_in_last_piece = 0; | │ │ │ │ │ +| int m_piece_size = 0; | │ │ │ │ │ +| std::int64_t m_total_size = 0; | │ │ │ │ │ | | │ │ │ │ │ -| // the time of next tracker announce | │ │ │ │ │ -| time_point32 next_announce = (time_point32::min)(); | │ │ │ │ │ +| // the number of filtered pieces that we don't already | │ │ │ │ │ +| // have. total_number_of_pieces - number_of_pieces_we_have | │ │ │ │ │ +| // - num_filtered is supposed to the number of pieces | │ │ │ │ │ +| // we still want to download | │ │ │ │ │ +|int m_num_filtered = 0; | │ │ │ │ │ | | │ │ │ │ │ -| // no announces before this time | │ │ │ │ │ -| time_point32 min_announce = (time_point32::min)(); | │ │ │ │ │ +| // the number of pieces we have that also are filtered | │ │ │ │ │ +| int m_num_have_filtered = 0; | │ │ │ │ │ | | │ │ │ │ │ +| // we have all pieces in the range [0, m_cursor) | │ │ │ │ │ +| // m_cursor is the first piece we don't have | │ │ │ │ │ +| piece_index_t m_cursor{0}; | │ │ │ │ │ | | │ │ │ │ │ -|// these are either -1 or the scrape information this tracker last | │ │ │ │ │ -| // responded with. *incomplete* is the current number of downloaders in | │ │ │ │ │ -| // the swarm, *complete* is the current number of seeds in the swarm and | │ │ │ │ │ -| // *downloaded* is the cumulative number of completed downloads of this | │ │ │ │ │ -| // torrent, since the beginning of time (from this tracker's point of | │ │ │ │ │ -| // view). | │ │ │ │ │ +| // we have all pieces in the range [m_reverse_cursor, end) | │ │ │ │ │ +| // m_reverse_cursor is the first piece where we also have | │ │ │ │ │ +| // all the subsequent pieces | │ │ │ │ │ +| piece_index_t m_reverse_cursor{0}; | │ │ │ │ │ | | │ │ │ │ │ -| // if this tracker has returned scrape data, these fields are filled in | │ │ │ │ │ -| // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts | │ │ │ │ │ -| // the number of current downloaders. ``complete`` counts the number of | │ │ │ │ │ -| // current peers completed the download, or "seeds". ``downloaded`` is the | │ │ │ │ │ -| // cumulative number of completed downloads. | │ │ │ │ │ -| int scrape_incomplete = -1; | │ │ │ │ │ -| int scrape_complete = -1; | │ │ │ │ │ -| int scrape_downloaded = -1; | │ │ │ │ │ +| // the number of pieces we have (i.e. passed hash check). | │ │ │ │ │ +| // This includes pieces that we have filtered but still have | │ │ │ │ │ +| int m_num_have = 0; | │ │ │ │ │ | | │ │ │ │ │ -| // the number of times in a row we have failed to announce to this | │ │ │ │ │ -| // tracker. | │ │ │ │ │ -| std::uint8_t fails : 7; | │ │ │ │ │ +| // if this is set to true, it means update_pieces() | │ │ │ │ │ +| // has to be called before accessing m_pieces. | │ │ │ │ │ +| mutable bool m_dirty = false; | │ │ │ │ │ +| public: | │ │ │ │ │ | | │ │ │ │ │ -| // true while we're waiting for a response from the tracker. | │ │ │ │ │ -| bool updating : 1; | │ │ │ │ │ +| enum { max_pieces = (std::numeric_limits::max)() - 1 }; | │ │ │ │ │ | | │ │ │ │ │ -| // set to true when we get a valid response from an announce | │ │ │ │ │ -| // with event=started. If it is set, we won't send start in the subsequent | │ │ │ │ │ -| // announces. | │ │ │ │ │ -| bool start_sent : 1; | │ │ │ │ │ +| }; | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| // set to true when we send a event=completed. | │ │ │ │ │ -|_ _ _b_o_o_l_ _c_o_m_p_l_e_t_e___s_e_n_t_ _:_ _1_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_#_e_n_d_i_f_ _/_/_ _T_O_R_R_E_N_T___P_I_E_C_E___P_I_C_K_E_R___H_P_P___I_N_C_L_U_D_E_D_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |make this a raw pointer. perhaps keep the shared_ptr around further down the object to maintain an owner | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_t_o_r_r_e_n_t_._h_p_p_:_2_8_0_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmaakkee tthhiiss aa rraaww ppooiinntteerr.. ppeerrhhaappss kkeeeepp tthhee sshhaarreedd__ppttrr aarroouunndd ffuurrtthheerr ddoowwnn tthhee oobbjjeecctt ttoo mmaaiinnttaaiinn aann oowwnneerr ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ttoorrrreenntt..hhpppp::228800 ****** | │ │ │ │ │ |#endif | │ │ │ │ │ | }; | │ │ │ │ │ | | │ │ │ │ │ @@ -11442,14 +11411,108 @@ │ │ │ │ │ | // remember that this is an SSL torrent, so that we don't | │ │ │ │ │ | // accidentally start seeding it without any authentication. | │ │ │ │ │ | bool m_ssl_torrent:1; | │ │ │ │ │ | | │ │ │ │ │ | // this is set to true if we're trying to delete the | │ │ │ │ │ | // files belonging to it. When set, don't write any | │ │ │ │ │ |_ _ _/_/_ _m_o_r_e_ _b_l_o_c_k_s_ _t_o_ _d_i_s_k_!_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |some space could be saved here by making gauges 32 bits | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._h_p_p_:_4_8_5_ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssoommee ssppaaccee ccoouulldd bbee ssaavveedd hheerree bbyy mmaakkiinngg ggaauuggeess 3322 bbiittss ********** | │ │ │ │ │ +|_**_**_**_ _.._.._//_ii_nn_cc_ll_uu_dd_ee_//_ll_ii_bb_tt_oo_rr_rr_ee_nn_tt_//_pp_ee_rr_ff_oo_rr_mm_aa_nn_cc_ee____cc_oo_uu_nn_tt_ee_rr_ss_.._hh_pp_pp_::_44_88_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |restore these to regular integers. Instead have one copy of the counters per thread and collect them at convenient synchronization | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._h_p_p_:_4_8_6_ _ _|_p_o_i_n_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** rreessttoorree tthheessee ttoo rreegguullaarr iinntteeggeerrss.. IInnsstteeaadd hhaavvee oonnee ccooppyy ooff tthhee ccoouunntteerrss ppeerr tthhrreeaadd aanndd ccoolllleecctt tthheemm aatt ccoonnvveenniieenntt ssyynncchhrroonniizzaattiioonn ppooiinnttss ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppeerrffoorrmmaannccee__ccoouunntteerrss..hhpppp::448866 ****** | │ │ │ │ │ +|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ +|#define TORRENT_COUNTER_NOEXCEPT noexcept | │ │ │ │ │ +|#else | │ │ │ │ │ +|#define TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| counters() TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| | │ │ │ │ │ +| counters(counters const&) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| counters& operator=(counters const&) & TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| | │ │ │ │ │ +| // returns the new value | │ │ │ │ │ +| std::int64_t inc_stats_counter(int c, std::int64_t value = 1) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| std::int64_t operator[](int i) const TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| | │ │ │ │ │ +| void set_value(int c, std::int64_t value) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| void blend_stats_counter(int c, std::int64_t value, int ratio) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ +| | │ │ │ │ │ +| private: | │ │ │ │ │ +| | │ │ │ │ │ +|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ +|aux::array, num_counters> m_stats_counter; | │ │ │ │ │ +|#else | │ │ │ │ │ +| // if the atomic type isn't lock-free, use a single lock instead, for | │ │ │ │ │ +| // the whole array | │ │ │ │ │ +| mutable std::mutex m_mutex; | │ │ │ │ │ +| aux::array m_stats_counter; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| }; | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |include the number of peers received from this tracker, at last announce | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_a_n_n_o_u_n_c_e___e_n_t_r_y_._h_p_p_:_7_6_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinncclluuddee tthhee nnuummbbeerr ooff ppeeeerrss rreecceeiivveedd ffrroomm tthhiiss ttrraacckkeerr,, aatt llaasstt aannnnoouunnccee ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aannnnoouunnccee__eennttrryy..hhpppp::7766 ****** | │ │ │ │ │ +| struct TORRENT_EXPORT announce_infohash | │ │ │ │ │ +| { | │ │ │ │ │ +| // internal | │ │ │ │ │ +| TORRENT_UNEXPORT announce_infohash(); | │ │ │ │ │ +| | │ │ │ │ │ +| // if this tracker has returned an error or warning message | │ │ │ │ │ +| // that message is stored here | │ │ │ │ │ +| std::string message; | │ │ │ │ │ +| | │ │ │ │ │ +| // if this tracker failed the last time it was contacted | │ │ │ │ │ +| // this error code specifies what error occurred | │ │ │ │ │ +| error_code last_error; | │ │ │ │ │ +| | │ │ │ │ │ +| // the time of next tracker announce | │ │ │ │ │ +| time_point32 next_announce = (time_point32::min)(); | │ │ │ │ │ +| | │ │ │ │ │ +| // no announces before this time | │ │ │ │ │ +| time_point32 min_announce = (time_point32::min)(); | │ │ │ │ │ +| | │ │ │ │ │ +| | │ │ │ │ │ +|// these are either -1 or the scrape information this tracker last | │ │ │ │ │ +| // responded with. *incomplete* is the current number of downloaders in | │ │ │ │ │ +| // the swarm, *complete* is the current number of seeds in the swarm and | │ │ │ │ │ +| // *downloaded* is the cumulative number of completed downloads of this | │ │ │ │ │ +| // torrent, since the beginning of time (from this tracker's point of | │ │ │ │ │ +| // view). | │ │ │ │ │ +| | │ │ │ │ │ +| // if this tracker has returned scrape data, these fields are filled in | │ │ │ │ │ +| // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts | │ │ │ │ │ +| // the number of current downloaders. ``complete`` counts the number of | │ │ │ │ │ +| // current peers completed the download, or "seeds". ``downloaded`` is the | │ │ │ │ │ +| // cumulative number of completed downloads. | │ │ │ │ │ +| int scrape_incomplete = -1; | │ │ │ │ │ +| int scrape_complete = -1; | │ │ │ │ │ +| int scrape_downloaded = -1; | │ │ │ │ │ +| | │ │ │ │ │ +| // the number of times in a row we have failed to announce to this | │ │ │ │ │ +| // tracker. | │ │ │ │ │ +| std::uint8_t fails : 7; | │ │ │ │ │ +| | │ │ │ │ │ +| // true while we're waiting for a response from the tracker. | │ │ │ │ │ +| bool updating : 1; | │ │ │ │ │ +| | │ │ │ │ │ +| // set to true when we get a valid response from an announce | │ │ │ │ │ +| // with event=started. If it is set, we won't send start in the subsequent | │ │ │ │ │ +| // announces. | │ │ │ │ │ +| bool start_sent : 1; | │ │ │ │ │ +| | │ │ │ │ │ +| // set to true when we send a event=completed. | │ │ │ │ │ +|_ _ _b_o_o_l_ _c_o_m_p_l_e_t_e___s_e_n_t_ _:_ _1_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ | |_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ | | │ │ │ │ │ |relevance 0|_p_e_e_r___c_o_n_n_e_c_t_i_o_n___i_n_t_e_r_f_a_c_e_._h_p_p_:|make this interface smaller! | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_5_1_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmaakkee tthhiiss iinntteerrffaaccee ssmmaalllleerr!! ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppeeeerr__ccoonnnneeccttiioonn__iinntteerrffaaccee..hhpppp::5511 ****** | │ │ │ │ │ |*/ | │ │ │ │ │ | | │ │ │ │ │ @@ -11497,121 +11560,208 @@ │ │ │ │ │ | virtual stat const& statistics() const = 0; | │ │ │ │ │ | virtual void get_peer_info(peer_info& p) const = 0; | │ │ │ │ │ |#ifndef TORRENT_DISABLE_LOGGING | │ │ │ │ │ | virtual bool should_log(peer_log_alert::direction_t direction) const = 0; | │ │ │ │ │ | virtual void peer_log(peer_log_alert::direction_t direction | │ │ │ │ │ | , char const* event, char const* fmt = "", ...) const noexcept TORRENT_FORMAT(4,5) = 0; | │ │ │ │ │ |_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |should this be allocated lazily? | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_i_e_c_e___p_i_c_k_e_r_._h_p_p_:_8_2_3_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** sshhoouulldd tthhiiss bbee aallllooccaatteedd llaazziillyy?? ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppiieeccee__ppiicckkeerr..hhpppp::882233 ****** | │ │ │ │ │ -|// download list it may live in now | │ │ │ │ │ -| std::vector::iterator update_piece_state( | │ │ │ │ │ -| std::vector::iterator dp); | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |support batched adding of block hashes for reduced overhead? | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_h_a_s_h___p_i_c_k_e_r_._h_p_p_:_1_5_5_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssuuppppoorrtt bbaattcchheedd aaddddiinngg ooff bblloocckk hhaasshheess ffoorr rreedduucceedd oovveerrhheeaadd?? ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//hhaasshh__ppiicckkeerr..hhpppp::115555 ****** | │ │ │ │ │ +|// the number of hashes in the range | │ │ │ │ │ +| int count = 0; | │ │ │ │ │ +| int proof_layers = 0; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| // validates the hash_request, to ensure its invariant as well as matching | │ │ │ │ │ +| // the torrent's file_storage and the number of hashes accompanying the | │ │ │ │ │ +| // request | │ │ │ │ │ +| TORRENT_EXTRA_EXPORT | │ │ │ │ │ +| bool validate_hash_request(hash_request const& hr, file_storage const& fs); | │ │ │ │ │ +| | │ │ │ │ │ +| class TORRENT_EXTRA_EXPORT hash_picker | │ │ │ │ │ +| { | │ │ │ │ │ +| public: | │ │ │ │ │ +| hash_picker(file_storage const& files | │ │ │ │ │ +| , aux::vector& trees); | │ │ │ │ │ +| | │ │ │ │ │ +| hash_request pick_hashes(typed_bitfield const& pieces); | │ │ │ │ │ +| | │ │ │ │ │ +| add_hashes_result add_hashes(hash_request const& req, span hashes); | │ │ │ │ │ +|set_block_hash_result set_block_hash(piece_index_t piece, int offset, sha256_hash const& h); | │ │ │ │ │ +|void hashes_rejected(hash_request const& req); | │ │ │ │ │ +| void verify_block_hashes(piece_index_t index); | │ │ │ │ │ +| | │ │ │ │ │ +| // do we know the piece layer hash for a piece | │ │ │ │ │ +| bool have_hash(piece_index_t index) const; | │ │ │ │ │ +| // do we know all the block hashes for a file? | │ │ │ │ │ +| bool have_all(file_index_t file) const; | │ │ │ │ │ +| bool have_all() const; | │ │ │ │ │ +| bool piece_verified(piece_index_t piece) const; | │ │ │ │ │ +| | │ │ │ │ │ +| int piece_layer() const { return m_piece_layer; } | │ │ │ │ │ | | │ │ │ │ │ | private: | │ │ │ │ │ +| // returns the number of proof layers needed to verify the node's hash | │ │ │ │ │ +| int layers_to_verify(node_index idx) const; | │ │ │ │ │ +| int file_num_layers(file_index_t idx) const; | │ │ │ │ │ | | │ │ │ │ │ -|#if TORRENT_USE_ASSERTS || TORRENT_USE_INVARIANT_CHECKS | │ │ │ │ │ -| index_range categories() const | │ │ │ │ │ -| { return {{}, piece_picker::piece_pos::num_download_categories}; } | │ │ │ │ │ +| struct piece_hash_request | │ │ │ │ │ +| { | │ │ │ │ │ +| time_point last_request = min_time(); | │ │ │ │ │ +| int num_requests = 0; | │ │ │ │ │ +| bool have = false; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| struct priority_block_request | │ │ │ │ │ +| { | │ │ │ │ │ +| priority_block_request(file_index_t const f, int const b) | │ │ │ │ │ +| : file(f), block(b) {} | │ │ │ │ │ +| file_index_t file; | │ │ │ │ │ +|_ _ _ _i_n_t_ _b_l_o_c_k_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |hide this declaration when deprecated functions are disabled, and remove its internal use | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_i_d_e_n_t_i_f_y___c_l_i_e_n_t_._h_p_p_:_4_8_ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** hhiiddee tthhiiss ddeeccllaarraattiioonn wwhheenn ddeepprreeccaatteedd ffuunnccttiioonnss aarree ddiissaabblleedd,, aanndd rreemmoovvee iittss iinntteerrnnaall uussee ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//iiddeennttiiffyy__cclliieenntt..hhpppp::4488 ****** | │ │ │ │ │ +|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ +|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ +|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ +| | │ │ │ │ │ +|*/ | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED | │ │ │ │ │ +|#define TORRENT_IDENTIFY_CLIENT_HPP_INCLUDED | │ │ │ │ │ +| | │ │ │ │ │ +|#include "libtorrent/config.hpp" | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| // the following vectors are mutable because they sometimes may | │ │ │ │ │ -| // be updated lazily, triggered by const functions | │ │ │ │ │ +|#include "libtorrent/peer_id.hpp" | │ │ │ │ │ +|#include "libtorrent/fingerprint.hpp" | │ │ │ │ │ | | │ │ │ │ │ -| // this maps indices to number of peers that has this piece and | │ │ │ │ │ -| // index into the m_piece_info vectors. | │ │ │ │ │ -| // piece_pos::we_have_index means that we have the piece, so it | │ │ │ │ │ -| // doesn't exist in the piece_info buckets | │ │ │ │ │ -| // pieces with the filtered flag set doesn't have entries in | │ │ │ │ │ -| // the m_piece_info buckets either | │ │ │ │ │ -|mutable aux::vector m_piece_map; | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ | | │ │ │ │ │ -| // tracks the number of bytes in a specific piece that are part of a pad | │ │ │ │ │ -| // file. The padding is assumed to be at the end of the piece, and the | │ │ │ │ │ -| // blocks covered by the pad bytes are not picked by the piece picker | │ │ │ │ │ -| std::unordered_map m_pads_in_piece; | │ │ │ │ │ +|namespace aux { | │ │ │ │ │ | | │ │ │ │ │ -| // when the adjacent_piece affinity is enabled, this contains the most | │ │ │ │ │ -| // recent "extents" of adjacent pieces that have been requested from | │ │ │ │ │ -| // this is mutable because it's updated by functions to pick pieces, which | │ │ │ │ │ -| // are const. That's an efficient place to update it, since it's being | │ │ │ │ │ -| // traversed already. | │ │ │ │ │ -| mutable std::vector m_recent_extents; | │ │ │ │ │ +| TORRENT_EXTRA_EXPORT | │ │ │ │ │ +| std::string identify_client_impl(const peer_id& p); | │ │ │ │ │ | | │ │ │ │ │ -| // the number of bytes of pad file set in this piece picker | │ │ │ │ │ -| std::int64_t m_num_pad_bytes = 0; | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ -| // the number of pad blocks that we already have | │ │ │ │ │ -| std::int64_t m_have_pad_bytes = 0; | │ │ │ │ │ +| // these functions don't really need to be public. This mechanism of | │ │ │ │ │ +| // advertising client software and version is also out-dated. | │ │ │ │ │ | | │ │ │ │ │ -| // the number of pad blocks part of filtered pieces we don't have | │ │ │ │ │ -| std::int64_t m_filtered_pad_bytes = 0; | │ │ │ │ │ +| // This function can can be used to extract a string describing a client | │ │ │ │ │ +| // version from its peer-id. It will recognize most clients that have this | │ │ │ │ │ +| // kind of identification in the peer-id. | │ │ │ │ │ +| TORRENT_DEPRECATED_EXPORT | │ │ │ │ │ +| std::string identify_client(const peer_id& p); | │ │ │ │ │ | | │ │ │ │ │ -| // the number of pad blocks we have that are also filtered | │ │ │ │ │ -| std::int64_t m_have_filtered_pad_bytes = 0; | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ | | │ │ │ │ │ -| // the number of seeds. These are not added to | │ │ │ │ │ -| // the availability counters of the pieces | │ │ │ │ │ -| int m_seeds = 0; | │ │ │ │ │ +|#include "libtorrent/aux_/disable_deprecation_warnings_push.hpp" | │ │ │ │ │ | | │ │ │ │ │ -|_ _ _/_/_ _t_h_i_s_ _v_e_c_t_o_r_ _c_o_n_t_a_i_n_s_ _a_l_l_ _p_i_e_c_e_ _i_n_d_i_c_e_s_ _t_h_a_t_ _a_r_e_ _p_i_c_k_a_b_l_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |it would be more intuitive to account "wanted" pieces instead of filtered | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_i_e_c_e___p_i_c_k_e_r_._h_p_p_:_8_9_5_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee mmoorree iinnttuuiittiivvee ttoo aaccccoouunntt ""wwaanntteedd"" ppiieecceess iinnsstteeaadd ooff ffiilltteerreedd ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppiieeccee__ppiicckkeerr..hhpppp::889955 ****** | │ │ │ │ │ -| // this holds the information of the blocks in partially downloaded | │ │ │ │ │ -| // pieces. the downloading_piece::info index point into this vector for | │ │ │ │ │ -| // its storage | │ │ │ │ │ -| aux::vector m_block_info; | │ │ │ │ │ +| // Returns an optional fingerprint if any can be identified from the peer | │ │ │ │ │ +| // id. This can be used to automate the identification of clients. It will | │ │ │ │ │ +| // not be able to identify peers with non- standard encodings. Only Azureus | │ │ │ │ │ +| // style, Shadow's style and Mainline style. | │ │ │ │ │ +| TORRENT_DEPRECATED_EXPORT | │ │ │ │ │ +| boost::optional | │ │ │ │ │ +| client_fingerprint(peer_id const& p); | │ │ │ │ │ | | │ │ │ │ │ -| // these are block ranges in m_block_info that are free. The numbers | │ │ │ │ │ -| // in here, when multiplied by blocks_per_piece is the index to the | │ │ │ │ │ -| // first block in the range that's free to use by a new downloading_piece. | │ │ │ │ │ -| // this is a free-list. | │ │ │ │ │ -| std::vector m_free_block_infos; | │ │ │ │ │ +|_#_i_n_c_l_u_d_e_ _"_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/_d_i_s_a_b_l_e___w_a_r_n_i_n_g_s___p_o_p_._h_p_p_"_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |support using the windows API for UPnP operations as well | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_u_p_n_p_._h_p_p_:_1_6_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ssuuppppoorrtt uussiinngg tthhee wwiinnddoowwss AAPPII ffoorr UUPPnnPP ooppeerraattiioonnss aass wweellll ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//uuppnnpp..hhpppp::116622 ****** | │ │ │ │ │ +|{ | │ │ │ │ │ +| bool in_error_code = false; | │ │ │ │ │ +| bool exit = false; | │ │ │ │ │ +| int error_code = -1; | │ │ │ │ │ +|}; | │ │ │ │ │ | | │ │ │ │ │ -| std::uint16_t m_blocks_in_last_piece = 0; | │ │ │ │ │ -| int m_piece_size = 0; | │ │ │ │ │ -| std::int64_t m_total_size = 0; | │ │ │ │ │ +|struct ip_address_parse_state: error_code_parse_state | │ │ │ │ │ +|{ | │ │ │ │ │ +| bool in_ip_address = false; | │ │ │ │ │ +| std::string ip_address; | │ │ │ │ │ +|}; | │ │ │ │ │ | | │ │ │ │ │ -| // the number of filtered pieces that we don't already | │ │ │ │ │ -| // have. total_number_of_pieces - number_of_pieces_we_have | │ │ │ │ │ -| // - num_filtered is supposed to the number of pieces | │ │ │ │ │ -| // we still want to download | │ │ │ │ │ -|int m_num_filtered = 0; | │ │ │ │ │ +|TORRENT_EXTRA_EXPORT void find_control_url(int type, string_view, parse_state& state); | │ │ │ │ │ | | │ │ │ │ │ -| // the number of pieces we have that also are filtered | │ │ │ │ │ -| int m_num_have_filtered = 0; | │ │ │ │ │ +|TORRENT_EXTRA_EXPORT void find_error_code(int type, string_view string | │ │ │ │ │ +| , error_code_parse_state& state); | │ │ │ │ │ | | │ │ │ │ │ -| // we have all pieces in the range [0, m_cursor) | │ │ │ │ │ -| // m_cursor is the first piece we don't have | │ │ │ │ │ -| piece_index_t m_cursor{0}; | │ │ │ │ │ +|TORRENT_EXTRA_EXPORT void find_ip_address(int type, string_view string | │ │ │ │ │ +| , ip_address_parse_state& state); | │ │ │ │ │ | | │ │ │ │ │ -| // we have all pieces in the range [m_reverse_cursor, end) | │ │ │ │ │ -| // m_reverse_cursor is the first piece where we also have | │ │ │ │ │ -| // all the subsequent pieces | │ │ │ │ │ -| piece_index_t m_reverse_cursor{0}; | │ │ │ │ │ +|struct TORRENT_EXTRA_EXPORT upnp final | │ │ │ │ │ +|: std::enable_shared_from_this | │ │ │ │ │ +| , single_threaded | │ │ │ │ │ +|{ | │ │ │ │ │ +| upnp(io_context& ios | │ │ │ │ │ +| , aux::session_settings const& settings | │ │ │ │ │ +| , aux::portmap_callback& cb | │ │ │ │ │ +| , address_v4 listen_address | │ │ │ │ │ +| , address_v4 netmask | │ │ │ │ │ +| , std::string listen_device | │ │ │ │ │ +| , aux::listen_socket_handle ls); | │ │ │ │ │ +| ~upnp(); | │ │ │ │ │ | | │ │ │ │ │ -| // the number of pieces we have (i.e. passed hash check). | │ │ │ │ │ -| // This includes pieces that we have filtered but still have | │ │ │ │ │ -| int m_num_have = 0; | │ │ │ │ │ +| void start(); | │ │ │ │ │ | | │ │ │ │ │ -| // if this is set to true, it means update_pieces() | │ │ │ │ │ -| // has to be called before accessing m_pieces. | │ │ │ │ │ -| mutable bool m_dirty = false; | │ │ │ │ │ -| public: | │ │ │ │ │ +| // Attempts to add a port mapping for the specified protocol. Valid protocols are | │ │ │ │ │ +| // ``upnp::tcp`` and ``upnp::udp`` for the UPnP class and ``natpmp::tcp`` and | │ │ │ │ │ +| // ``natpmp::udp`` for the NAT-PMP class. | │ │ │ │ │ +| // | │ │ │ │ │ +| // ``external_port`` is the port on the external address that will be mapped. This | │ │ │ │ │ +| // is a hint, you are not guaranteed that this port will be available, and it may | │ │ │ │ │ +| // end up being something else. In the portmap_alert_ notification, the actual | │ │ │ │ │ +| // external port is reported. | │ │ │ │ │ +| // | │ │ │ │ │ +| // ``local_port`` is the port in the local machine that the mapping should forward | │ │ │ │ │ +| // to. | │ │ │ │ │ +| // | │ │ │ │ │ +| // The return value is an index that identifies this port mapping. This is used | │ │ │ │ │ +| // to refer to mappings that fails or succeeds in the portmap_error_alert_ and | │ │ │ │ │ +| // portmap_alert_ respectively. If The mapping fails immediately, the return value | │ │ │ │ │ +|_ _/_/_ _i_s_ _-_1_,_ _w_h_i_c_h_ _m_e_a_n_s_ _f_a_i_l_u_r_e_._ _T_h_e_r_e_ _w_i_l_l_ _n_o_t_ _b_e_ _a_n_y_ _e_r_r_o_r_ _a_l_e_r_t_ _n_o_t_i_f_i_c_a_t_i_o_n_ _f_o_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |move to aux | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_o_c_k_e_t___t_y_p_e_._h_p_p_:_6_0_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmoovvee ttoo aauuxx ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssoocckkeett__ttyyppee..hhpppp::6600 ****** | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ | | │ │ │ │ │ -| enum { max_pieces = (std::numeric_limits::max)() - 1 }; | │ │ │ │ │ +|// A type describing kinds of sockets involved in various operations or events. | │ │ │ │ │ +|enum class socket_type_t : std::uint8_t { | │ │ │ │ │ +| tcp, | │ │ │ │ │ +| socks5, | │ │ │ │ │ +| http, | │ │ │ │ │ +| utp, | │ │ │ │ │ +| i2p, | │ │ │ │ │ +| tcp_ssl, | │ │ │ │ │ +| socks5_ssl, | │ │ │ │ │ +| http_ssl, | │ │ │ │ │ +| utp_ssl, | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION <= 2 | │ │ │ │ │ +| udp TORRENT_DEPRECATED_ENUM = utp, | │ │ │ │ │ +|#endif | │ │ │ │ │ +|}; | │ │ │ │ │ +| | │ │ │ │ │ +|// return a short human readable name for types of socket | │ │ │ │ │ +|char const* socket_type_name(socket_type_t); | │ │ │ │ │ | | │ │ │ │ │ -| }; | │ │ │ │ │ |} | │ │ │ │ │ | | │ │ │ │ │ -|_#_e_n_d_i_f_ _/_/_ _T_O_R_R_E_N_T___P_I_E_C_E___P_I_C_K_E_R___H_P_P___I_N_C_L_U_D_E_D_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |make this a string_view | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_i_2_p___s_t_r_e_a_m_._h_p_p_:_5_3_3_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmaakkee tthhiiss aa ssttrriinngg__vviieeww ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ii22pp__ssttrreeaamm..hhpppp::553333 ****** | │ │ │ │ │ | char tmp[20]; | │ │ │ │ │ | aux::random_bytes(tmp); | │ │ │ │ │ | m_session_id.resize(sizeof(tmp)*2); | │ │ │ │ │ @@ -11658,14 +11808,69 @@ │ │ │ │ │ | return; | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ | do_name_lookup("ME", wrap_allocator( | │ │ │ │ │ | [this](error_code const& e, char const* dst, Handler hn) { | │ │ │ │ │ | set_local_endpoint(e, dst, std::move(hn)); | │ │ │ │ │ |_ _ _ _}_,_ _s_t_d_:_:_m_o_v_e_(_h_)_)_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |it would be nice to remember the bind port and bind once we know where the proxy is m_sock.bind(endpoint, ec); | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_r_o_x_y___b_a_s_e_._h_p_p_:_2_2_7_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo rreemmeemmbbeerr tthhee bbiinndd ppoorrtt aanndd bbiinndd oonnccee wwee kknnooww wwhheerree tthhee pprrooxxyy iiss mm__ssoocckk..bbiinndd((eennddppooiinntt,, eecc));; ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//pprrooxxyy__bbaassee..hhpppp::222277 ****** | │ │ │ │ │ +|TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +| m_sock.cancel(); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void cancel(error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +| m_sock.cancel(ec); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| void bind(endpoint_type const& /* endpoint */, error_code& /* ec */) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +| // the reason why we ignore binds here is because we don't | │ │ │ │ │ +| // (necessarily) yet know what address family the proxy | │ │ │ │ │ +| // will resolve to, and binding to the wrong one would | │ │ │ │ │ +| // break our connection attempt later. The caller here | │ │ │ │ │ +| // doesn't necessarily know that we're proxying, so this | │ │ │ │ │ +| // bind address is based on the final endpoint, not the | │ │ │ │ │ +| // proxy. | │ │ │ │ │ +|} | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ +| void open(protocol_type const&) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +|// m_sock.open(p); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| void open(protocol_type const&, error_code&) | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +| // we need to ignore this for the same reason as stated | │ │ │ │ │ +| // for ignoring bind() | │ │ │ │ │ +|// m_sock.open(p, ec); | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ +| void close() | │ │ │ │ │ +| { | │ │ │ │ │ +| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ +| m_remote_endpoint = endpoint_type(); | │ │ │ │ │ +| m_sock.close(); | │ │ │ │ │ +| m_resolver.cancel(); | │ │ │ │ │ +| } | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| void close(error_code& ec) | │ │ │ │ │ +| { | │ │ │ │ │ +|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T_(_m___m_a_g_i_c_ _=_=_ _0_x_1_3_3_7_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |replace this by the standard string_view in C++17 | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_s_t_r_i_n_g___v_i_e_w_._h_p_p_:_4_0_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** rreeppllaaccee tthhiiss bbyy tthhee ssttaannddaarrdd ssttrriinngg__vviieeww iinn CC++++1177 ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssttrriinngg__vviieeww..hhpppp::4400 ****** | │ │ │ │ │ |AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | │ │ │ │ │ |IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | │ │ │ │ │ |ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | │ │ │ │ │ @@ -11713,124 +11918,69 @@ │ │ │ │ │ |{ | │ │ │ │ │ | while (pos < v.size()) | │ │ │ │ │ | { | │ │ │ │ │ | if (std::strchr(c, v[pos]) != nullptr) return pos; | │ │ │ │ │ | ++pos; | │ │ │ │ │ | } | │ │ │ │ │ |_ _r_e_t_u_r_n_ _s_t_r_i_n_g___v_i_e_w_:_:_n_p_o_s_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |support batched adding of block hashes for reduced overhead? | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_h_a_s_h___p_i_c_k_e_r_._h_p_p_:_1_5_5_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssuuppppoorrtt bbaattcchheedd aaddddiinngg ooff bblloocckk hhaasshheess ffoorr rreedduucceedd oovveerrhheeaadd?? ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//hhaasshh__ppiicckkeerr..hhpppp::115555 ****** | │ │ │ │ │ -|// the number of hashes in the range | │ │ │ │ │ -| int count = 0; | │ │ │ │ │ -| int proof_layers = 0; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| // validates the hash_request, to ensure its invariant as well as matching | │ │ │ │ │ -| // the torrent's file_storage and the number of hashes accompanying the | │ │ │ │ │ -| // request | │ │ │ │ │ -| TORRENT_EXTRA_EXPORT | │ │ │ │ │ -| bool validate_hash_request(hash_request const& hr, file_storage const& fs); | │ │ │ │ │ -| | │ │ │ │ │ -| class TORRENT_EXTRA_EXPORT hash_picker | │ │ │ │ │ -| { | │ │ │ │ │ -| public: | │ │ │ │ │ -| hash_picker(file_storage const& files | │ │ │ │ │ -| , aux::vector& trees); | │ │ │ │ │ -| | │ │ │ │ │ -| hash_request pick_hashes(typed_bitfield const& pieces); | │ │ │ │ │ -| | │ │ │ │ │ -| add_hashes_result add_hashes(hash_request const& req, span hashes); | │ │ │ │ │ -|set_block_hash_result set_block_hash(piece_index_t piece, int offset, sha256_hash const& h); | │ │ │ │ │ -|void hashes_rejected(hash_request const& req); | │ │ │ │ │ -| void verify_block_hashes(piece_index_t index); | │ │ │ │ │ -| | │ │ │ │ │ -| // do we know the piece layer hash for a piece | │ │ │ │ │ -| bool have_hash(piece_index_t index) const; | │ │ │ │ │ -| // do we know all the block hashes for a file? | │ │ │ │ │ -| bool have_all(file_index_t file) const; | │ │ │ │ │ -| bool have_all() const; | │ │ │ │ │ -| bool piece_verified(piece_index_t piece) const; | │ │ │ │ │ -| | │ │ │ │ │ -| int piece_layer() const { return m_piece_layer; } | │ │ │ │ │ -| | │ │ │ │ │ -| private: | │ │ │ │ │ -| // returns the number of proof layers needed to verify the node's hash | │ │ │ │ │ -| int layers_to_verify(node_index idx) const; | │ │ │ │ │ -| int file_num_layers(file_index_t idx) const; | │ │ │ │ │ -| | │ │ │ │ │ -| struct piece_hash_request | │ │ │ │ │ -| { | │ │ │ │ │ -| time_point last_request = min_time(); | │ │ │ │ │ -| int num_requests = 0; | │ │ │ │ │ -| bool have = false; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| struct priority_block_request | │ │ │ │ │ -| { | │ │ │ │ │ -| priority_block_request(file_index_t const f, int const b) | │ │ │ │ │ -| : file(f), block(b) {} | │ │ │ │ │ -| file_index_t file; | │ │ │ │ │ -|_ _ _ _i_n_t_ _b_l_o_c_k_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |it would be nice to remember the bind port and bind once we know where the proxy is m_sock.bind(endpoint, ec); | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_r_o_x_y___b_a_s_e_._h_p_p_:_2_2_7_ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo rreemmeemmbbeerr tthhee bbiinndd ppoorrtt aanndd bbiinndd oonnccee wwee kknnooww wwhheerree tthhee pprrooxxyy iiss mm__ssoocckk..bbiinndd((eennddppooiinntt,, eecc));; ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//pprrooxxyy__bbaassee..hhpppp::222277 ****** | │ │ │ │ │ -|TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -| m_sock.cancel(); | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |we could bind the socket here, since we know what the target endpoint is of the proxy | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_o_c_k_s_5___s_t_r_e_a_m_._h_p_p_:_1_9_7_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** wwee ccoouulldd bbiinndd tthhee ssoocckkeett hheerree,, ssiinnccee wwee kknnooww wwhhaatt tthhee ttaarrggeett eennddppooiinntt iiss ooff tthhee pprrooxxyy ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssoocckkss55__ssttrreeaamm..hhpppp::119977 ****** | │ │ │ │ │ +|}, std::move(handler))); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -| void cancel(error_code& ec) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -| m_sock.cancel(ec); | │ │ │ │ │ -| } | │ │ │ │ │ +|private: | │ │ │ │ │ | | │ │ │ │ │ -| void bind(endpoint_type const& /* endpoint */, error_code& /* ec */) | │ │ │ │ │ +| template | │ │ │ │ │ +| void name_lookup(error_code const& e, tcp::resolver::results_type ips | │ │ │ │ │ +| , Handler h) | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -| // the reason why we ignore binds here is because we don't | │ │ │ │ │ -| // (necessarily) yet know what address family the proxy | │ │ │ │ │ -| // will resolve to, and binding to the wrong one would | │ │ │ │ │ -| // break our connection attempt later. The caller here | │ │ │ │ │ -| // doesn't necessarily know that we're proxying, so this | │ │ │ │ │ -| // bind address is based on the final endpoint, not the | │ │ │ │ │ -| // proxy. | │ │ │ │ │ -|} | │ │ │ │ │ +| COMPLETE_ASYNC("socks5_stream::name_lookup"); | │ │ │ │ │ +| if (handle_error(e, std::move(h))) return; | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ -| void open(protocol_type const&) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -|// m_sock.open(p); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ +| auto i = ips.begin(); | │ │ │ │ │ +| if (!m_sock.is_open()) | │ │ │ │ │ +| { | │ │ │ │ │ +| error_code ec; | │ │ │ │ │ +| m_sock.open(i->endpoint().protocol(), ec); | │ │ │ │ │ +| if (handle_error(ec, std::move(h))) return; | │ │ │ │ │ +| } | │ │ │ │ │ | | │ │ │ │ │ -| void open(protocol_type const&, error_code&) | │ │ │ │ │ -| { | │ │ │ │ │ -| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -| // we need to ignore this for the same reason as stated | │ │ │ │ │ -| // for ignoring bind() | │ │ │ │ │ -|// m_sock.open(p, ec); | │ │ │ │ │ +|ADD_OUTSTANDING_ASYNC("socks5_stream::connected"); | │ │ │ │ │ +|m_sock.async_connect(i->endpoint(), wrap_allocator( | │ │ │ │ │ +| [this](error_code const& ec, Handler hn) | │ │ │ │ │ +| { connected(ec, std::move(hn)); }, std::move(h))); | │ │ │ │ │ | } | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef BOOST_NO_EXCEPTIONS | │ │ │ │ │ -| void close() | │ │ │ │ │ +| template | │ │ │ │ │ +| void connected(error_code const& e, Handler h) | │ │ │ │ │ | { | │ │ │ │ │ -| TORRENT_ASSERT(m_magic == 0x1337); | │ │ │ │ │ -| m_remote_endpoint = endpoint_type(); | │ │ │ │ │ -| m_sock.close(); | │ │ │ │ │ -| m_resolver.cancel(); | │ │ │ │ │ -| } | │ │ │ │ │ -|#endif | │ │ │ │ │ +| COMPLETE_ASYNC("socks5_stream::connected"); | │ │ │ │ │ +| if (handle_error(e, std::move(h))) return; | │ │ │ │ │ | | │ │ │ │ │ -| void close(error_code& ec) | │ │ │ │ │ -| { | │ │ │ │ │ -|_ _ _T_O_R_R_E_N_T___A_S_S_E_R_T_(_m___m_a_g_i_c_ _=_=_ _0_x_1_3_3_7_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +| using namespace libtorrent::aux; | │ │ │ │ │ +| if (m_version == 5) | │ │ │ │ │ +| { | │ │ │ │ │ +| // send SOCKS5 authentication methods | │ │ │ │ │ +| m_buffer.resize(m_user.empty()?3:4); | │ │ │ │ │ +| char* p = &m_buffer[0]; | │ │ │ │ │ +| write_uint8(5, p); // SOCKS VERSION 5 | │ │ │ │ │ +| if (m_user.empty()) | │ │ │ │ │ +| { | │ │ │ │ │ +| write_uint8(1, p); // 1 authentication method (no auth) | │ │ │ │ │ +| write_uint8(0, p); // no authentication | │ │ │ │ │ +| } | │ │ │ │ │ +| else | │ │ │ │ │ +| { | │ │ │ │ │ +| write_uint8(2, p); // 2 authentication methods | │ │ │ │ │ +| write_uint8(0, p); // no authentication | │ │ │ │ │ +| write_uint8(2, p); // username/password | │ │ │ │ │ +| } | │ │ │ │ │ +|_ _ _ _A_D_D___O_U_T_S_T_A_N_D_I_N_G___A_S_Y_N_C_(_"_s_o_c_k_s_5___s_t_r_e_a_m_:_:_h_a_n_d_s_h_a_k_e_1_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |make this a raw pointer (to save size in the first cache line) and make the constructor take a raw pointer. torrent objects should | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_p_e_e_r___c_o_n_n_e_c_t_i_o_n_._h_p_p_:_2_1_8_ _ _ _ _ _ _ _|_a_l_w_a_y_s_ _o_u_t_l_i_v_e_ _t_h_e_i_r_ _p_e_e_r_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmaakkee tthhiiss aa rraaww ppooiinntteerr ((ttoo ssaavvee ssiizzee iinn tthhee ffiirrsstt ccaacchhee lliinnee)) aanndd mmaakkee tthhee ccoonnssttrruuccttoorr ttaakkee aa rraaww ppooiinntteerr.. ttoorrrreenntt oobbjjeeccttss sshhoouulldd aallwwaayyss oouuttlliivvee tthheeiirr ppeeeerrss ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppeeeerr__ccoonnnneeccttiioonn..hhpppp::221188 ****** | │ │ │ │ │ |, m_snubbed(false) | │ │ │ │ │ | , m_interesting(false) | │ │ │ │ │ | , m_choked(true) | │ │ │ │ │ @@ -11932,164 +12082,14 @@ │ │ │ │ │ | // let plugins control flags that should always be set | │ │ │ │ │ | picker_options_t m_picker_options{}; | │ │ │ │ │ | | │ │ │ │ │ | // the number of invalid piece-requests | │ │ │ │ │ | // we have got from this peer. If the request | │ │ │ │ │ | // queue gets empty, and there have been | │ │ │ │ │ |_ _ _/_/_ _i_n_v_a_l_i_d_ _r_e_q_u_e_s_t_s_,_ _w_e_ _c_a_n_ _a_s_s_u_m_e_ _t_h_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |we could bind the socket here, since we know what the target endpoint is of the proxy | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_o_c_k_s_5___s_t_r_e_a_m_._h_p_p_:_1_9_7_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** wwee ccoouulldd bbiinndd tthhee ssoocckkeett hheerree,, ssiinnccee wwee kknnooww wwhhaatt tthhee ttaarrggeett eennddppooiinntt iiss ooff tthhee pprrooxxyy ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ssoocckkss55__ssttrreeaamm..hhpppp::119977 ****** | │ │ │ │ │ -|}, std::move(handler))); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|private: | │ │ │ │ │ -| | │ │ │ │ │ -| template | │ │ │ │ │ -| void name_lookup(error_code const& e, tcp::resolver::results_type ips | │ │ │ │ │ -| , Handler h) | │ │ │ │ │ -| { | │ │ │ │ │ -| COMPLETE_ASYNC("socks5_stream::name_lookup"); | │ │ │ │ │ -| if (handle_error(e, std::move(h))) return; | │ │ │ │ │ -| | │ │ │ │ │ -| auto i = ips.begin(); | │ │ │ │ │ -| if (!m_sock.is_open()) | │ │ │ │ │ -| { | │ │ │ │ │ -| error_code ec; | │ │ │ │ │ -| m_sock.open(i->endpoint().protocol(), ec); | │ │ │ │ │ -| if (handle_error(ec, std::move(h))) return; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -|ADD_OUTSTANDING_ASYNC("socks5_stream::connected"); | │ │ │ │ │ -|m_sock.async_connect(i->endpoint(), wrap_allocator( | │ │ │ │ │ -| [this](error_code const& ec, Handler hn) | │ │ │ │ │ -| { connected(ec, std::move(hn)); }, std::move(h))); | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| template | │ │ │ │ │ -| void connected(error_code const& e, Handler h) | │ │ │ │ │ -| { | │ │ │ │ │ -| COMPLETE_ASYNC("socks5_stream::connected"); | │ │ │ │ │ -| if (handle_error(e, std::move(h))) return; | │ │ │ │ │ -| | │ │ │ │ │ -| using namespace libtorrent::aux; | │ │ │ │ │ -| if (m_version == 5) | │ │ │ │ │ -| { | │ │ │ │ │ -| // send SOCKS5 authentication methods | │ │ │ │ │ -| m_buffer.resize(m_user.empty()?3:4); | │ │ │ │ │ -| char* p = &m_buffer[0]; | │ │ │ │ │ -| write_uint8(5, p); // SOCKS VERSION 5 | │ │ │ │ │ -| if (m_user.empty()) | │ │ │ │ │ -| { | │ │ │ │ │ -| write_uint8(1, p); // 1 authentication method (no auth) | │ │ │ │ │ -| write_uint8(0, p); // no authentication | │ │ │ │ │ -| } | │ │ │ │ │ -| else | │ │ │ │ │ -| { | │ │ │ │ │ -| write_uint8(2, p); // 2 authentication methods | │ │ │ │ │ -| write_uint8(0, p); // no authentication | │ │ │ │ │ -| write_uint8(2, p); // username/password | │ │ │ │ │ -| } | │ │ │ │ │ -|_ _ _ _A_D_D___O_U_T_S_T_A_N_D_I_N_G___A_S_Y_N_C_(_"_s_o_c_k_s_5___s_t_r_e_a_m_:_:_h_a_n_d_s_h_a_k_e_1_"_)_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |support using the windows API for UPnP operations as well | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_u_p_n_p_._h_p_p_:_1_6_2_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssuuppppoorrtt uussiinngg tthhee wwiinnddoowwss AAPPII ffoorr UUPPnnPP ooppeerraattiioonnss aass wweellll ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//uuppnnpp..hhpppp::116622 ****** | │ │ │ │ │ -|{ | │ │ │ │ │ -| bool in_error_code = false; | │ │ │ │ │ -| bool exit = false; | │ │ │ │ │ -| int error_code = -1; | │ │ │ │ │ -|}; | │ │ │ │ │ -| | │ │ │ │ │ -|struct ip_address_parse_state: error_code_parse_state | │ │ │ │ │ -|{ | │ │ │ │ │ -| bool in_ip_address = false; | │ │ │ │ │ -| std::string ip_address; | │ │ │ │ │ -|}; | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_EXTRA_EXPORT void find_control_url(int type, string_view, parse_state& state); | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_EXTRA_EXPORT void find_error_code(int type, string_view string | │ │ │ │ │ -| , error_code_parse_state& state); | │ │ │ │ │ -| | │ │ │ │ │ -|TORRENT_EXTRA_EXPORT void find_ip_address(int type, string_view string | │ │ │ │ │ -| , ip_address_parse_state& state); | │ │ │ │ │ -| | │ │ │ │ │ -|struct TORRENT_EXTRA_EXPORT upnp final | │ │ │ │ │ -|: std::enable_shared_from_this | │ │ │ │ │ -| , single_threaded | │ │ │ │ │ -|{ | │ │ │ │ │ -| upnp(io_context& ios | │ │ │ │ │ -| , aux::session_settings const& settings | │ │ │ │ │ -| , aux::portmap_callback& cb | │ │ │ │ │ -| , address_v4 listen_address | │ │ │ │ │ -| , address_v4 netmask | │ │ │ │ │ -| , std::string listen_device | │ │ │ │ │ -| , aux::listen_socket_handle ls); | │ │ │ │ │ -| ~upnp(); | │ │ │ │ │ -| | │ │ │ │ │ -| void start(); | │ │ │ │ │ -| | │ │ │ │ │ -| // Attempts to add a port mapping for the specified protocol. Valid protocols are | │ │ │ │ │ -| // ``upnp::tcp`` and ``upnp::udp`` for the UPnP class and ``natpmp::tcp`` and | │ │ │ │ │ -| // ``natpmp::udp`` for the NAT-PMP class. | │ │ │ │ │ -| // | │ │ │ │ │ -| // ``external_port`` is the port on the external address that will be mapped. This | │ │ │ │ │ -| // is a hint, you are not guaranteed that this port will be available, and it may | │ │ │ │ │ -| // end up being something else. In the portmap_alert_ notification, the actual | │ │ │ │ │ -| // external port is reported. | │ │ │ │ │ -| // | │ │ │ │ │ -| // ``local_port`` is the port in the local machine that the mapping should forward | │ │ │ │ │ -| // to. | │ │ │ │ │ -| // | │ │ │ │ │ -| // The return value is an index that identifies this port mapping. This is used | │ │ │ │ │ -| // to refer to mappings that fails or succeeds in the portmap_error_alert_ and | │ │ │ │ │ -| // portmap_alert_ respectively. If The mapping fails immediately, the return value | │ │ │ │ │ -|_ _/_/_ _i_s_ _-_1_,_ _w_h_i_c_h_ _m_e_a_n_s_ _f_a_i_l_u_r_e_._ _T_h_e_r_e_ _w_i_l_l_ _n_o_t_ _b_e_ _a_n_y_ _e_r_r_o_r_ _a_l_e_r_t_ _n_o_t_i_f_i_c_a_t_i_o_n_ _f_o_r_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |some space could be saved here by making gauges 32 bits | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._h_p_p_:_4_8_5_ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ssoommee ssppaaccee ccoouulldd bbee ssaavveedd hheerree bbyy mmaakkiinngg ggaauuggeess 3322 bbiittss ********** | │ │ │ │ │ -|_**_**_**_ _.._.._//_ii_nn_cc_ll_uu_dd_ee_//_ll_ii_bb_tt_oo_rr_rr_ee_nn_tt_//_pp_ee_rr_ff_oo_rr_mm_aa_nn_cc_ee____cc_oo_uu_nn_tt_ee_rr_ss_.._hh_pp_pp_::_44_88_55_ _**_**_**_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |restore these to regular integers. Instead have one copy of the counters per thread and collect them at convenient synchronization | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_e_r_f_o_r_m_a_n_c_e___c_o_u_n_t_e_r_s_._h_p_p_:_4_8_6_ _ _|_p_o_i_n_t_s_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** rreessttoorree tthheessee ttoo rreegguullaarr iinntteeggeerrss.. IInnsstteeaadd hhaavvee oonnee ccooppyy ooff tthhee ccoouunntteerrss ppeerr tthhrreeaadd aanndd ccoolllleecctt tthheemm aatt ccoonnvveenniieenntt ssyynncchhrroonniizzaattiioonn ppooiinnttss ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//ppeerrffoorrmmaannccee__ccoouunntteerrss..hhpppp::448866 ****** | │ │ │ │ │ -|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ -|#define TORRENT_COUNTER_NOEXCEPT noexcept | │ │ │ │ │ -|#else | │ │ │ │ │ -|#define TORRENT_COUNTER_NOEXCEPT | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| counters() TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| | │ │ │ │ │ -| counters(counters const&) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| counters& operator=(counters const&) & TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| | │ │ │ │ │ -| // returns the new value | │ │ │ │ │ -| std::int64_t inc_stats_counter(int c, std::int64_t value = 1) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| std::int64_t operator[](int i) const TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| | │ │ │ │ │ -| void set_value(int c, std::int64_t value) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| void blend_stats_counter(int c, std::int64_t value, int ratio) TORRENT_COUNTER_NOEXCEPT; | │ │ │ │ │ -| | │ │ │ │ │ -| private: | │ │ │ │ │ -| | │ │ │ │ │ -|#ifdef ATOMIC_LLONG_LOCK_FREE | │ │ │ │ │ -|aux::array, num_counters> m_stats_counter; | │ │ │ │ │ -|#else | │ │ │ │ │ -| // if the atomic type isn't lock-free, use a single lock instead, for | │ │ │ │ │ -| // the whole array | │ │ │ │ │ -| mutable std::mutex m_mutex; | │ │ │ │ │ -| aux::array m_stats_counter; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| }; | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ -|_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/ |move this to its own .hpp/.cpp pair? | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_k_a_d_e_m_l_i_a_/_m_s_g_._h_p_p_:_8_7_ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** mmoovvee tthhiiss ttoo iittss oowwnn ..hhpppp//..ccpppp ppaaiirr?? ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//kkaaddeemmlliiaa//mmssgg..hhpppp::8877 ****** | │ │ │ │ │ |int flags; | │ │ │ │ │ | | │ │ │ │ │ | enum { | │ │ │ │ │ @@ -12177,328 +12177,58 @@ │ │ │ │ │ | , secret_key const& sk); | │ │ │ │ │ | explicit item(bdecode_node const& v); | │ │ │ │ │ | | │ │ │ │ │ | void assign(entry v); | │ │ │ │ │ | void assign(entry v, span salt | │ │ │ │ │ | , sequence_number seq | │ │ │ │ │ |_ _ _,_ _p_u_b_l_i_c___k_e_y_ _c_o_n_s_t_&_ _p_k_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |it would be nice to not have this be part of session_interface | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_n_t_e_r_f_a_c_e_._h_p_p_:_2_1_2_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iitt wwoouulldd bbee nniiccee ttoo nnoott hhaavvee tthhiiss bbee ppaarrtt ooff sseessssiioonn__iinntteerrffaaccee ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iinntteerrffaaccee..hhpppp::221122 ****** | │ │ │ │ │ -|virtual void deferred_submit_jobs() = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual std::uint16_t listen_port() const = 0; | │ │ │ │ │ -| virtual std::uint16_t ssl_listen_port() const = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual int listen_port(aux::transport ssl, address const& local_addr) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual void for_each_listen_socket(std::function f) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| // ask for which interface and port to bind outgoing peer connections on | │ │ │ │ │ -| virtual tcp::endpoint bind_outgoing_socket(socket_type& s, address const& | │ │ │ │ │ -| remote_address, error_code& ec) const = 0; | │ │ │ │ │ -| virtual bool verify_bound_address(address const& addr, bool utp | │ │ │ │ │ -| , error_code& ec) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ -| virtual std::vector> find_collection( | │ │ │ │ │ -| std::string const& collection) const = 0; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -|virtual proxy_settings proxy() const = 0; | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_USE_I2P | │ │ │ │ │ -| virtual char const* i2p_session() const = 0; | │ │ │ │ │ -| virtual std::string const& local_i2p_endpoint() const = 0; | │ │ │ │ │ -|#endif | │ │ │ │ │ -| | │ │ │ │ │ -| virtual void prioritize_connections(std::weak_ptr t) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual void trigger_auto_manage() = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual void apply_settings_pack(std::shared_ptr pack) = 0; | │ │ │ │ │ -| virtual session_settings const& settings() const = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual void queue_tracker_request(tracker_request req | │ │ │ │ │ -| , std::weak_ptr c) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| // peer-classes | │ │ │ │ │ -| virtual void set_peer_classes(peer_class_set* s, address const& a, socket_type_t st) = 0; | │ │ │ │ │ -| virtual peer_class_pool const& peer_classes() const = 0; | │ │ │ │ │ -| virtual peer_class_pool& peer_classes() = 0; | │ │ │ │ │ -| virtual bool ignore_unchoke_slots_set(peer_class_set const& set) const = 0; | │ │ │ │ │ -| virtual int copy_pertinent_channels(peer_class_set const& set | │ │ │ │ │ -| , int channel, bandwidth_channel** dst, int m) = 0; | │ │ │ │ │ -| virtual int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual bandwidth_manager* get_bandwidth_manager(int channel) = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| virtual void sent_bytes(int bytes_payload, int bytes_protocol) = 0; | │ │ │ │ │ -| virtual void received_bytes(int bytes_payload, int bytes_protocol) = 0; | │ │ │ │ │ -|_ _ _v_i_r_t_u_a_l_ _v_o_i_d_ _t_r_a_n_c_i_e_v_e___i_p___p_a_c_k_e_t_(_i_n_t_ _b_y_t_e_s_,_ _b_o_o_l_ _i_p_v_6_)_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |make these direct members and generate shared_ptrs to them which alias the listen_socket_t shared_ptr | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_2_6_5_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** mmaakkee tthheessee ddiirreecctt mmeemmbbeerrss aanndd ggeenneerraattee sshhaarreedd__ppttrrss ttoo tthheemm wwhhiicchh aalliiaass tthhee lliisstteenn__ssoocckkeett__tt sshhaarreedd__ppttrr ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::226655 ****** | │ │ │ │ │ -|if (udp_sock) return udp_sock->sock.local_port(); | │ │ │ │ │ -| return 0; | │ │ │ │ │ -| } | │ │ │ │ │ -| | │ │ │ │ │ -| // 0 is natpmp 1 is upnp | │ │ │ │ │ -| // the order of these arrays determines the priority in | │ │ │ │ │ -| // which their ports will be announced to peers | │ │ │ │ │ -| aux::array tcp_port_mapping; | │ │ │ │ │ -| aux::array udp_port_mapping; | │ │ │ │ │ -| | │ │ │ │ │ -| // indicates whether this is an SSL listen socket or not | │ │ │ │ │ -| transport ssl = transport::plaintext; | │ │ │ │ │ -| | │ │ │ │ │ -| listen_socket_flags_t flags = accept_incoming; | │ │ │ │ │ -| | │ │ │ │ │ -| // the actual sockets (TCP listen socket and UDP socket) | │ │ │ │ │ -| // An entry does not necessarily have a UDP or TCP socket. One of these | │ │ │ │ │ -| // pointers may be nullptr! | │ │ │ │ │ -| // These must be shared_ptr to avoid a dangling reference if an | │ │ │ │ │ -| // incoming packet is in the event queue when the socket is erased | │ │ │ │ │ -|std::shared_ptr sock; | │ │ │ │ │ -|std::shared_ptr udp_sock; | │ │ │ │ │ -| | │ │ │ │ │ -| // since udp packets are expected to be dispatched frequently, this saves | │ │ │ │ │ -| // time on handler allocation every time we read again. | │ │ │ │ │ -| aux::handler_storage udp_handler_storage; | │ │ │ │ │ -| | │ │ │ │ │ -| std::shared_ptr natpmp_mapper; | │ │ │ │ │ -| std::shared_ptr upnp_mapper; | │ │ │ │ │ -| | │ │ │ │ │ -| std::shared_ptr lsd; | │ │ │ │ │ -| | │ │ │ │ │ -| // set to true when we receive an incoming connection from this listen | │ │ │ │ │ -| // socket | │ │ │ │ │ -| bool incoming_connection = false; | │ │ │ │ │ -| }; | │ │ │ │ │ -| | │ │ │ │ │ -| struct TORRENT_EXTRA_EXPORT listen_endpoint_t | │ │ │ │ │ -| { | │ │ │ │ │ -| listen_endpoint_t(address const& adr, int p, std::string dev, transport s | │ │ │ │ │ -| , listen_socket_flags_t f, address const& nmask = address{}) | │ │ │ │ │ -| : addr(adr), netmask(nmask), port(p), device(std::move(dev)), ssl(s), flags(f) {} | │ │ │ │ │ -| | │ │ │ │ │ -| bool operator==(listen_endpoint_t const& o) const | │ │ │ │ │ -| { | │ │ │ │ │ -| return addr == o.addr | │ │ │ │ │ -| && port == o.port | │ │ │ │ │ -| && device == o.device | │ │ │ │ │ -| && ssl == o.ssl | │ │ │ │ │ -| && flags == o.flags; | │ │ │ │ │ -|_ _ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |replace this by a proper asio timer | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_1_0_6_8_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** rreeppllaaccee tthhiiss bbyy aa pprrooppeerr aassiioo ttiimmeerr ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::11006688 ****** | │ │ │ │ │ -|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ -| void on_incoming_utp_ssl(socket_type s); | │ │ │ │ │ -| void ssl_handshake(error_code const& ec, socket_type* s); | │ │ │ │ │ -|#endif | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |figure out which version of clang this is supported in | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_d_e_p_r_e_c_a_t_e_d_._h_p_p_:_4_7_ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** ffiigguurree oouutt wwhhiicchh vveerrssiioonn ooff ccllaanngg tthhiiss iiss ssuuppppoorrtteedd iinn ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//ddeepprreeccaatteedd..hhpppp::4477 ****** | │ │ │ │ │ +|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ +|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ +|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ | | │ │ │ │ │ -| // round-robin index into m_outgoing_interfaces | │ │ │ │ │ -| mutable std::uint8_t m_interface_index = 0; | │ │ │ │ │ +|*/ | │ │ │ │ │ | | │ │ │ │ │ -| std::shared_ptr setup_listener( | │ │ │ │ │ -| listen_endpoint_t const& lep, error_code& ec); | │ │ │ │ │ +|#ifndef TORRENT_DEPRECATED_HPP_INCLUDED | │ │ │ │ │ +|#define TORRENT_DEPRECATED_HPP_INCLUDED | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| dht::dht_state m_dht_state; | │ │ │ │ │ +|#if !defined TORRENT_BUILDING_LIBRARY | │ │ │ │ │ +|# define TORRENT_DEPRECATED [[deprecated]] | │ │ │ │ │ +|#else | │ │ │ │ │ +|# define TORRENT_DEPRECATED | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| // this is initialized to the unchoke_interval | │ │ │ │ │ -| // session_setting and decreased every second. | │ │ │ │ │ -| // when it reaches zero, it is reset to the | │ │ │ │ │ -| // unchoke_interval and the unchoke set is | │ │ │ │ │ -| // recomputed. | │ │ │ │ │ -|int m_unchoke_time_scaler = 0; | │ │ │ │ │ +|#if defined __clang__ | │ │ │ │ │ | | │ │ │ │ │ -| // this is used to decide when to recalculate which | │ │ │ │ │ -|_ _ _ _/_/_ _t_o_r_r_e_n_t_s_ _t_o_ _k_e_e_p_ _q_u_e_u_e_d_ _a_n_d_ _w_h_i_c_h_ _t_o_ _a_c_t_i_v_a_t_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |replace this by a proper asio timer | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_1_0_7_3_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** rreeppllaaccee tthhiiss bbyy aa pprrooppeerr aassiioo ttiimmeerr ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::11007733 ****** | │ │ │ │ │ -| // round-robin index into m_outgoing_interfaces | │ │ │ │ │ -| mutable std::uint8_t m_interface_index = 0; | │ │ │ │ │ +|// ====== CLANG ======== | │ │ │ │ │ | | │ │ │ │ │ -| std::shared_ptr setup_listener( | │ │ │ │ │ -| listen_endpoint_t const& lep, error_code& ec); | │ │ │ │ │ +|# if !defined TORRENT_BUILDING_LIBRARY | │ │ │ │ │ +|# define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) | │ │ │ │ │ +|# endif | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| dht::dht_state m_dht_state; | │ │ │ │ │ -|#endif | │ │ │ │ │ +|#elif defined __GNUC__ | │ │ │ │ │ | | │ │ │ │ │ -| // this is initialized to the unchoke_interval | │ │ │ │ │ -| // session_setting and decreased every second. | │ │ │ │ │ -| // when it reaches zero, it is reset to the | │ │ │ │ │ -| // unchoke_interval and the unchoke set is | │ │ │ │ │ -| // recomputed. | │ │ │ │ │ -| int m_unchoke_time_scaler = 0; | │ │ │ │ │ +|// ======== GCC ======== | │ │ │ │ │ | | │ │ │ │ │ -| // this is used to decide when to recalculate which | │ │ │ │ │ -| // torrents to keep queued and which to activate | │ │ │ │ │ -|int m_auto_manage_time_scaler = 0; | │ │ │ │ │ +|// deprecation markup is only enabled when libtorrent | │ │ │ │ │ +|// headers are included by clients, not while building | │ │ │ │ │ +|// libtorrent itself | │ │ │ │ │ +|# if __GNUC__ >= 6 && !defined TORRENT_BUILDING_LIBRARY | │ │ │ │ │ +|# define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) | │ │ │ │ │ +|# endif | │ │ │ │ │ | | │ │ │ │ │ -| // works like unchoke_time_scaler but it | │ │ │ │ │ -| // is only decreased when the unchoke set | │ │ │ │ │ -| // is recomputed, and when it reaches zero, | │ │ │ │ │ -|_ _ _ _/_/_ _t_h_e_ _o_p_t_i_m_i_s_t_i_c_ _u_n_c_h_o_k_e_ _i_s_ _m_o_v_e_d_ _t_o_ _a_n_o_t_h_e_r_ _p_e_e_r_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |replace this by a proper asio timer | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_1_0_8_0_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** rreeppllaaccee tthhiiss bbyy aa pprrooppeerr aassiioo ttiimmeerr ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::11008800 ****** | │ │ │ │ │ -|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ -| dht::dht_state m_dht_state; | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| // this is initialized to the unchoke_interval | │ │ │ │ │ -| // session_setting and decreased every second. | │ │ │ │ │ -| // when it reaches zero, it is reset to the | │ │ │ │ │ -| // unchoke_interval and the unchoke set is | │ │ │ │ │ -| // recomputed. | │ │ │ │ │ -| int m_unchoke_time_scaler = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| // this is used to decide when to recalculate which | │ │ │ │ │ -| // torrents to keep queued and which to activate | │ │ │ │ │ -| int m_auto_manage_time_scaler = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| // works like unchoke_time_scaler but it | │ │ │ │ │ -| // is only decreased when the unchoke set | │ │ │ │ │ -| // is recomputed, and when it reaches zero, | │ │ │ │ │ -| // the optimistic unchoke is moved to another peer. | │ │ │ │ │ -|int m_optimistic_unchoke_time_scaler = 0; | │ │ │ │ │ -| | │ │ │ │ │ -| // works like unchoke_time_scaler. Each time | │ │ │ │ │ -| // it reaches 0, and all the connections are | │ │ │ │ │ -| // used, the worst connection will be disconnected | │ │ │ │ │ -| // from the torrent with the most peers | │ │ │ │ │ -| int m_disconnect_time_scaler = 90; | │ │ │ │ │ -| | │ │ │ │ │ -| // when this scaler reaches zero, it will | │ │ │ │ │ -| // scrape one of the auto managed, paused, | │ │ │ │ │ -| // torrents. | │ │ │ │ │ -| int m_auto_scrape_time_scaler = 180; | │ │ │ │ │ -| | │ │ │ │ │ -| // statistics gathered from all torrents. | │ │ │ │ │ -| stat m_stat; | │ │ │ │ │ -| | │ │ │ │ │ -| // implements session_interface | │ │ │ │ │ -| void sent_bytes(int bytes_payload, int bytes_protocol) override; | │ │ │ │ │ -| void received_bytes(int bytes_payload, int bytes_protocol) override; | │ │ │ │ │ -| void trancieve_ip_packet(int bytes, bool ipv6) override; | │ │ │ │ │ -| void sent_syn(bool ipv6) override; | │ │ │ │ │ -| void received_synack(bool ipv6) override; | │ │ │ │ │ -| | │ │ │ │ │ -|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ -| int m_peak_up_rate = 0; | │ │ │ │ │ +|#ifndef TORRENT_DEPRECATED_ENUM | │ │ │ │ │ +|#define TORRENT_DEPRECATED_ENUM | │ │ │ │ │ |#endif | │ │ │ │ │ | | │ │ │ │ │ -| void on_tick(error_code const& e); | │ │ │ │ │ -| | │ │ │ │ │ -| void try_connect_more_peers(); | │ │ │ │ │ -|_ _ _ _v_o_i_d_ _a_u_t_o___m_a_n_a_g_e___c_h_e_c_k_i_n_g___t_o_r_r_e_n_t_s_(_s_t_d_:_:_v_e_c_t_o_r_<_t_o_r_r_e_n_t_*_>_&_ _l_i_s_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |include the number of peers received from this tracker, at last announce | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_a_n_n_o_u_n_c_e___e_n_t_r_y_._h_p_p_:_7_4_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** iinncclluuddee tthhee nnuummbbeerr ooff ppeeeerrss rreecceeiivveedd ffrroomm tthhiiss ttrraacckkeerr,, aatt llaasstt aannnnoouunnccee ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//aannnnoouunnccee__eennttrryy..hhpppp::7744 ****** | │ │ │ │ │ -|namespace aux { | │ │ │ │ │ -| | │ │ │ │ │ -| struct TORRENT_EXTRA_EXPORT announce_infohash | │ │ │ │ │ -| { | │ │ │ │ │ -| announce_infohash(); | │ │ │ │ │ -| | │ │ │ │ │ -| // if this tracker has returned an error or warning message | │ │ │ │ │ -| // that message is stored here | │ │ │ │ │ -| std::string message; | │ │ │ │ │ -| | │ │ │ │ │ -| // if this tracker failed the last time it was contacted | │ │ │ │ │ -| // this error code specifies what error occurred | │ │ │ │ │ -| error_code last_error; | │ │ │ │ │ -| | │ │ │ │ │ -| // the time of next tracker announce | │ │ │ │ │ -| time_point32 next_announce = (time_point32::min)(); | │ │ │ │ │ -| | │ │ │ │ │ -| // no announces before this time | │ │ │ │ │ -| time_point32 min_announce = (time_point32::min)(); | │ │ │ │ │ -| | │ │ │ │ │ -| | │ │ │ │ │ -|// these are either -1 or the scrape information this tracker last | │ │ │ │ │ -| // responded with. *incomplete* is the current number of downloaders in | │ │ │ │ │ -| // the swarm, *complete* is the current number of seeds in the swarm and | │ │ │ │ │ -| // *downloaded* is the cumulative number of completed downloads of this | │ │ │ │ │ -| // torrent, since the beginning of time (from this tracker's point of | │ │ │ │ │ -| // view). | │ │ │ │ │ -| | │ │ │ │ │ -| // if this tracker has returned scrape data, these fields are filled in | │ │ │ │ │ -| // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts | │ │ │ │ │ -| // the number of current downloaders. ``complete`` counts the number of | │ │ │ │ │ -| // current peers completed the download, or "seeds". ``downloaded`` is the | │ │ │ │ │ -| // cumulative number of completed downloads. | │ │ │ │ │ -| int scrape_incomplete = -1; | │ │ │ │ │ -| int scrape_complete = -1; | │ │ │ │ │ -| int scrape_downloaded = -1; | │ │ │ │ │ -| | │ │ │ │ │ -| // the number of times in a row we have failed to announce to this | │ │ │ │ │ -| // tracker. | │ │ │ │ │ -| std::uint8_t fails : 7; | │ │ │ │ │ -| | │ │ │ │ │ -| // true while we're waiting for a response from the tracker. | │ │ │ │ │ -| bool updating : 1; | │ │ │ │ │ -| | │ │ │ │ │ -| // set to true when we get a valid response from an announce | │ │ │ │ │ -| // with event=started. If it is set, we won't send start in the subsequent | │ │ │ │ │ -| // announces. | │ │ │ │ │ -| bool start_sent : 1; | │ │ │ │ │ -| | │ │ │ │ │ -| // set to true when we send a event=completed. | │ │ │ │ │ -|_ _ _b_o_o_l_ _c_o_m_p_l_e_t_e___s_e_n_t_ _:_ _1_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |ensure the alignment is good here | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_p_o_o_l_._h_p_p_:_4_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** eennssuurree tthhee aalliiggnnmmeenntt iiss ggoooodd hheerree ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//ppooooll..hhpppp::4499 ****** | │ │ │ │ │ -|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ -| | │ │ │ │ │ -|*/ | │ │ │ │ │ -| | │ │ │ │ │ -|#ifndef TORRENT_POOL_HPP | │ │ │ │ │ -|#define TORRENT_POOL_HPP | │ │ │ │ │ -| | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include | │ │ │ │ │ -|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ -| | │ │ │ │ │ -|namespace libtorrent { | │ │ │ │ │ -|namespace aux { | │ │ │ │ │ -| | │ │ │ │ │ -|struct allocator_new_delete | │ │ │ │ │ -|{ | │ │ │ │ │ -| using size_type = std::size_t; | │ │ │ │ │ -| using difference_type = std::ptrdiff_t; | │ │ │ │ │ -| | │ │ │ │ │ -|static char* malloc(size_type const bytes) | │ │ │ │ │ -|{ return new char[bytes]; } | │ │ │ │ │ -| static void free(char* const block) | │ │ │ │ │ -| { delete [] block; } | │ │ │ │ │ -|}; | │ │ │ │ │ -| | │ │ │ │ │ -|using pool = boost::pool; | │ │ │ │ │ -| | │ │ │ │ │ -|template | │ │ │ │ │ -|using object_pool = boost::object_pool; | │ │ │ │ │ -| | │ │ │ │ │ -|} | │ │ │ │ │ -|} | │ │ │ │ │ -| | │ │ │ │ │ |_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |remove this constructor. Don't support "uninitialized" trees. This also requires not constructing these for pad-files and small | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_m_e_r_k_l_e___t_r_e_e_._h_p_p_:_8_5_ _ _ _ _ _ _ _ _ _ _ _ _|_f_i_l_e_s_ _a_s_ _w_e_l_l_._ _S_o_,_ _a_ _s_p_a_r_s_e_ _h_a_s_h_ _l_i_s_t_ _i_n_ _t_o_r_r_e_n_t___i_n_f_o_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** rreemmoovvee tthhiiss ccoonnssttrruuccttoorr.. DDoonn''tt ssuuppppoorrtt ""uunniinniittiiaalliizzeedd"" ttrreeeess.. TThhiiss aallssoo rreeqquuiirreess nnoott ccoonnssttrruuccttiinngg tthheessee ffoorr ppaadd--ffiilleess aanndd ssmmaallll ffiilleess aass wweellll.. SSoo,, aa ssppaarrssee hhaasshh lliisstt iinn | │ │ │ │ │ |ttoorrrreenntt__iinnffoo ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//mmeerrkkllee__ttrreeee..hhpppp::8855 ****** | │ │ │ │ │ |// The invariant of the tree is that all interior nodes (i.e. all but the very | │ │ │ │ │ @@ -12600,57 +12330,106 @@ │ │ │ │ │ | | │ │ │ │ │ | // we don't have any hashes in this tree. m_tree should be empty | │ │ │ │ │ | // an empty tree still always have the root hash (available as root()) | │ │ │ │ │ | empty_tree, | │ │ │ │ │ | | │ │ │ │ │ | // in this mode, m_tree represents the full tree, including padding. | │ │ │ │ │ |_ _ _f_u_l_l___t_r_e_e_,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |figure out which version of clang this is supported in | │ │ │ │ │ -|_ _ _ _ _ _ _ _ _ _ _ _|_d_e_p_r_e_c_a_t_e_d_._h_p_p_:_4_7_ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ -|********** ffiigguurree oouutt wwhhiicchh vveerrssiioonn ooff ccllaanngg tthhiiss iiss ssuuppppoorrtteedd iinn ********** | │ │ │ │ │ -|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//ddeepprreeccaatteedd..hhpppp::4477 ****** | │ │ │ │ │ -|CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | │ │ │ │ │ -|ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | │ │ │ │ │ -|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |include the number of peers received from this tracker, at last announce | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_a_n_n_o_u_n_c_e___e_n_t_r_y_._h_p_p_:_7_4_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iinncclluuddee tthhee nnuummbbeerr ooff ppeeeerrss rreecceeiivveedd ffrroomm tthhiiss ttrraacckkeerr,, aatt llaasstt aannnnoouunnccee ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//aannnnoouunnccee__eennttrryy..hhpppp::7744 ****** | │ │ │ │ │ +|namespace aux { | │ │ │ │ │ | | │ │ │ │ │ -|*/ | │ │ │ │ │ +| struct TORRENT_EXTRA_EXPORT announce_infohash | │ │ │ │ │ +| { | │ │ │ │ │ +| announce_infohash(); | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DEPRECATED_HPP_INCLUDED | │ │ │ │ │ -|#define TORRENT_DEPRECATED_HPP_INCLUDED | │ │ │ │ │ +| // if this tracker has returned an error or warning message | │ │ │ │ │ +| // that message is stored here | │ │ │ │ │ +| std::string message; | │ │ │ │ │ | | │ │ │ │ │ -|#if !defined TORRENT_BUILDING_LIBRARY | │ │ │ │ │ -|# define TORRENT_DEPRECATED [[deprecated]] | │ │ │ │ │ -|#else | │ │ │ │ │ -|# define TORRENT_DEPRECATED | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // if this tracker failed the last time it was contacted | │ │ │ │ │ +| // this error code specifies what error occurred | │ │ │ │ │ +| error_code last_error; | │ │ │ │ │ | | │ │ │ │ │ -|#if defined __clang__ | │ │ │ │ │ +| // the time of next tracker announce | │ │ │ │ │ +| time_point32 next_announce = (time_point32::min)(); | │ │ │ │ │ | | │ │ │ │ │ -|// ====== CLANG ======== | │ │ │ │ │ +| // no announces before this time | │ │ │ │ │ +| time_point32 min_announce = (time_point32::min)(); | │ │ │ │ │ | | │ │ │ │ │ -|# if !defined TORRENT_BUILDING_LIBRARY | │ │ │ │ │ -|# define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) | │ │ │ │ │ -|# endif | │ │ │ │ │ | | │ │ │ │ │ -|#elif defined __GNUC__ | │ │ │ │ │ +|// these are either -1 or the scrape information this tracker last | │ │ │ │ │ +| // responded with. *incomplete* is the current number of downloaders in | │ │ │ │ │ +| // the swarm, *complete* is the current number of seeds in the swarm and | │ │ │ │ │ +| // *downloaded* is the cumulative number of completed downloads of this | │ │ │ │ │ +| // torrent, since the beginning of time (from this tracker's point of | │ │ │ │ │ +| // view). | │ │ │ │ │ | | │ │ │ │ │ -|// ======== GCC ======== | │ │ │ │ │ +| // if this tracker has returned scrape data, these fields are filled in | │ │ │ │ │ +| // with valid numbers. Otherwise they are set to -1. ``incomplete`` counts | │ │ │ │ │ +| // the number of current downloaders. ``complete`` counts the number of | │ │ │ │ │ +| // current peers completed the download, or "seeds". ``downloaded`` is the | │ │ │ │ │ +| // cumulative number of completed downloads. | │ │ │ │ │ +| int scrape_incomplete = -1; | │ │ │ │ │ +| int scrape_complete = -1; | │ │ │ │ │ +| int scrape_downloaded = -1; | │ │ │ │ │ | | │ │ │ │ │ -|// deprecation markup is only enabled when libtorrent | │ │ │ │ │ -|// headers are included by clients, not while building | │ │ │ │ │ -|// libtorrent itself | │ │ │ │ │ -|# if __GNUC__ >= 6 && !defined TORRENT_BUILDING_LIBRARY | │ │ │ │ │ -|# define TORRENT_DEPRECATED_ENUM __attribute__ ((deprecated)) | │ │ │ │ │ -|# endif | │ │ │ │ │ +| // the number of times in a row we have failed to announce to this | │ │ │ │ │ +| // tracker. | │ │ │ │ │ +| std::uint8_t fails : 7; | │ │ │ │ │ | | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // true while we're waiting for a response from the tracker. | │ │ │ │ │ +| bool updating : 1; | │ │ │ │ │ | | │ │ │ │ │ -|#ifndef TORRENT_DEPRECATED_ENUM | │ │ │ │ │ -|#define TORRENT_DEPRECATED_ENUM | │ │ │ │ │ -|#endif | │ │ │ │ │ +| // set to true when we get a valid response from an announce | │ │ │ │ │ +| // with event=started. If it is set, we won't send start in the subsequent | │ │ │ │ │ +| // announces. | │ │ │ │ │ +| bool start_sent : 1; | │ │ │ │ │ +| | │ │ │ │ │ +| // set to true when we send a event=completed. | │ │ │ │ │ +|_ _ _b_o_o_l_ _c_o_m_p_l_e_t_e___s_e_n_t_ _:_ _1_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |ensure the alignment is good here | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_p_o_o_l_._h_p_p_:_4_9_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** eennssuurree tthhee aalliiggnnmmeenntt iiss ggoooodd hheerree ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//ppooooll..hhpppp::4499 ****** | │ │ │ │ │ +|POSSIBILITY OF SUCH DAMAGE. | │ │ │ │ │ +| | │ │ │ │ │ +|*/ | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_POOL_HPP | │ │ │ │ │ +|#define TORRENT_POOL_HPP | │ │ │ │ │ +| | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_push.hpp" | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include | │ │ │ │ │ +|#include "libtorrent/aux_/disable_warnings_pop.hpp" | │ │ │ │ │ +| | │ │ │ │ │ +|namespace libtorrent { | │ │ │ │ │ +|namespace aux { | │ │ │ │ │ +| | │ │ │ │ │ +|struct allocator_new_delete | │ │ │ │ │ +|{ | │ │ │ │ │ +| using size_type = std::size_t; | │ │ │ │ │ +| using difference_type = std::ptrdiff_t; | │ │ │ │ │ +| | │ │ │ │ │ +|static char* malloc(size_type const bytes) | │ │ │ │ │ +|{ return new char[bytes]; } | │ │ │ │ │ +| static void free(char* const block) | │ │ │ │ │ +| { delete [] block; } | │ │ │ │ │ +|}; | │ │ │ │ │ +| | │ │ │ │ │ +|using pool = boost::pool; | │ │ │ │ │ +| | │ │ │ │ │ +|template | │ │ │ │ │ +|using object_pool = boost::object_pool; | │ │ │ │ │ +| | │ │ │ │ │ +|} | │ │ │ │ │ +|} | │ │ │ │ │ | | │ │ │ │ │ |_#_e_n_d_i_f_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |in C++17, Handler and Storage could just use "auto" | │ │ │ │ │ |_ _ _ _ _ _ _ _ _ _ _ _|_a_l_l_o_c_a_t_i_n_g___h_a_n_d_l_e_r_._h_p_p_:_3_1_6_ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ |********** iinn CC++++1177,, HHaannddlleerr aanndd SSttoorraaggee ccoouulldd jjuusstt uussee ""aauuttoo"" ********** | │ │ │ │ │ |****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//aallllooccaattiinngg__hhaannddlleerr..hhpppp::331166 ****** | │ │ │ │ │ | private: | │ │ │ │ │ @@ -12754,7 +12533,228 @@ │ │ │ │ │ | // it's important that these match the enums in performance_counters for | │ │ │ │ │ | // num_utp_idle etc. | │ │ │ │ │ | enum class state_t { | │ │ │ │ │ | // not yet connected | │ │ │ │ │ | none, | │ │ │ │ │ | // sent a syn packet, not received any acks | │ │ │ │ │ |_ _ _s_y_n___s_e_n_t_,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |make these direct members and generate shared_ptrs to them which alias the listen_socket_t shared_ptr | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_2_6_5_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** mmaakkee tthheessee ddiirreecctt mmeemmbbeerrss aanndd ggeenneerraattee sshhaarreedd__ppttrrss ttoo tthheemm wwhhiicchh aalliiaass tthhee lliisstteenn__ssoocckkeett__tt sshhaarreedd__ppttrr ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::226655 ****** | │ │ │ │ │ +|if (udp_sock) return udp_sock->sock.local_port(); | │ │ │ │ │ +| return 0; | │ │ │ │ │ +| } | │ │ │ │ │ +| | │ │ │ │ │ +| // 0 is natpmp 1 is upnp | │ │ │ │ │ +| // the order of these arrays determines the priority in | │ │ │ │ │ +| // which their ports will be announced to peers | │ │ │ │ │ +| aux::array tcp_port_mapping; | │ │ │ │ │ +| aux::array udp_port_mapping; | │ │ │ │ │ +| | │ │ │ │ │ +| // indicates whether this is an SSL listen socket or not | │ │ │ │ │ +| transport ssl = transport::plaintext; | │ │ │ │ │ +| | │ │ │ │ │ +| listen_socket_flags_t flags = accept_incoming; | │ │ │ │ │ +| | │ │ │ │ │ +| // the actual sockets (TCP listen socket and UDP socket) | │ │ │ │ │ +| // An entry does not necessarily have a UDP or TCP socket. One of these | │ │ │ │ │ +| // pointers may be nullptr! | │ │ │ │ │ +| // These must be shared_ptr to avoid a dangling reference if an | │ │ │ │ │ +| // incoming packet is in the event queue when the socket is erased | │ │ │ │ │ +|std::shared_ptr sock; | │ │ │ │ │ +|std::shared_ptr udp_sock; | │ │ │ │ │ +| | │ │ │ │ │ +| // since udp packets are expected to be dispatched frequently, this saves | │ │ │ │ │ +| // time on handler allocation every time we read again. | │ │ │ │ │ +| aux::handler_storage udp_handler_storage; | │ │ │ │ │ +| | │ │ │ │ │ +| std::shared_ptr natpmp_mapper; | │ │ │ │ │ +| std::shared_ptr upnp_mapper; | │ │ │ │ │ +| | │ │ │ │ │ +| std::shared_ptr lsd; | │ │ │ │ │ +| | │ │ │ │ │ +| // set to true when we receive an incoming connection from this listen | │ │ │ │ │ +| // socket | │ │ │ │ │ +| bool incoming_connection = false; | │ │ │ │ │ +| }; | │ │ │ │ │ +| | │ │ │ │ │ +| struct TORRENT_EXTRA_EXPORT listen_endpoint_t | │ │ │ │ │ +| { | │ │ │ │ │ +| listen_endpoint_t(address const& adr, int p, std::string dev, transport s | │ │ │ │ │ +| , listen_socket_flags_t f, address const& nmask = address{}) | │ │ │ │ │ +| : addr(adr), netmask(nmask), port(p), device(std::move(dev)), ssl(s), flags(f) {} | │ │ │ │ │ +| | │ │ │ │ │ +| bool operator==(listen_endpoint_t const& o) const | │ │ │ │ │ +| { | │ │ │ │ │ +| return addr == o.addr | │ │ │ │ │ +| && port == o.port | │ │ │ │ │ +| && device == o.device | │ │ │ │ │ +| && ssl == o.ssl | │ │ │ │ │ +| && flags == o.flags; | │ │ │ │ │ +|_ _ _ _}_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |replace this by a proper asio timer | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_1_0_6_8_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** rreeppllaaccee tthhiiss bbyy aa pprrooppeerr aassiioo ttiimmeerr ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::11006688 ****** | │ │ │ │ │ +|#ifdef TORRENT_SSL_PEERS | │ │ │ │ │ +| void on_incoming_utp_ssl(socket_type s); | │ │ │ │ │ +| void ssl_handshake(error_code const& ec, socket_type* s); | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // round-robin index into m_outgoing_interfaces | │ │ │ │ │ +| mutable std::uint8_t m_interface_index = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| std::shared_ptr setup_listener( | │ │ │ │ │ +| listen_endpoint_t const& lep, error_code& ec); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| dht::dht_state m_dht_state; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // this is initialized to the unchoke_interval | │ │ │ │ │ +| // session_setting and decreased every second. | │ │ │ │ │ +| // when it reaches zero, it is reset to the | │ │ │ │ │ +| // unchoke_interval and the unchoke set is | │ │ │ │ │ +| // recomputed. | │ │ │ │ │ +|int m_unchoke_time_scaler = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // this is used to decide when to recalculate which | │ │ │ │ │ +|_ _ _ _/_/_ _t_o_r_r_e_n_t_s_ _t_o_ _k_e_e_p_ _q_u_e_u_e_d_ _a_n_d_ _w_h_i_c_h_ _t_o_ _a_c_t_i_v_a_t_e_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |replace this by a proper asio timer | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_1_0_7_3_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** rreeppllaaccee tthhiiss bbyy aa pprrooppeerr aassiioo ttiimmeerr ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::11007733 ****** | │ │ │ │ │ +| // round-robin index into m_outgoing_interfaces | │ │ │ │ │ +| mutable std::uint8_t m_interface_index = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| std::shared_ptr setup_listener( | │ │ │ │ │ +| listen_endpoint_t const& lep, error_code& ec); | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| dht::dht_state m_dht_state; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // this is initialized to the unchoke_interval | │ │ │ │ │ +| // session_setting and decreased every second. | │ │ │ │ │ +| // when it reaches zero, it is reset to the | │ │ │ │ │ +| // unchoke_interval and the unchoke set is | │ │ │ │ │ +| // recomputed. | │ │ │ │ │ +| int m_unchoke_time_scaler = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // this is used to decide when to recalculate which | │ │ │ │ │ +| // torrents to keep queued and which to activate | │ │ │ │ │ +|int m_auto_manage_time_scaler = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // works like unchoke_time_scaler but it | │ │ │ │ │ +| // is only decreased when the unchoke set | │ │ │ │ │ +| // is recomputed, and when it reaches zero, | │ │ │ │ │ +|_ _ _ _/_/_ _t_h_e_ _o_p_t_i_m_i_s_t_i_c_ _u_n_c_h_o_k_e_ _i_s_ _m_o_v_e_d_ _t_o_ _a_n_o_t_h_e_r_ _p_e_e_r_._ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |replace this by a proper asio timer | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_m_p_l_._h_p_p_:_1_0_8_0_ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** rreeppllaaccee tthhiiss bbyy aa pprrooppeerr aassiioo ttiimmeerr ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iimmppll..hhpppp::11008800 ****** | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_DHT | │ │ │ │ │ +| dht::dht_state m_dht_state; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| // this is initialized to the unchoke_interval | │ │ │ │ │ +| // session_setting and decreased every second. | │ │ │ │ │ +| // when it reaches zero, it is reset to the | │ │ │ │ │ +| // unchoke_interval and the unchoke set is | │ │ │ │ │ +| // recomputed. | │ │ │ │ │ +| int m_unchoke_time_scaler = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // this is used to decide when to recalculate which | │ │ │ │ │ +| // torrents to keep queued and which to activate | │ │ │ │ │ +| int m_auto_manage_time_scaler = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // works like unchoke_time_scaler but it | │ │ │ │ │ +| // is only decreased when the unchoke set | │ │ │ │ │ +| // is recomputed, and when it reaches zero, | │ │ │ │ │ +| // the optimistic unchoke is moved to another peer. | │ │ │ │ │ +|int m_optimistic_unchoke_time_scaler = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // works like unchoke_time_scaler. Each time | │ │ │ │ │ +| // it reaches 0, and all the connections are | │ │ │ │ │ +| // used, the worst connection will be disconnected | │ │ │ │ │ +| // from the torrent with the most peers | │ │ │ │ │ +| int m_disconnect_time_scaler = 90; | │ │ │ │ │ +| | │ │ │ │ │ +| // when this scaler reaches zero, it will | │ │ │ │ │ +| // scrape one of the auto managed, paused, | │ │ │ │ │ +| // torrents. | │ │ │ │ │ +| int m_auto_scrape_time_scaler = 180; | │ │ │ │ │ +| | │ │ │ │ │ +| // statistics gathered from all torrents. | │ │ │ │ │ +| stat m_stat; | │ │ │ │ │ +| | │ │ │ │ │ +| // implements session_interface | │ │ │ │ │ +| void sent_bytes(int bytes_payload, int bytes_protocol) override; | │ │ │ │ │ +| void received_bytes(int bytes_payload, int bytes_protocol) override; | │ │ │ │ │ +| void trancieve_ip_packet(int bytes, bool ipv6) override; | │ │ │ │ │ +| void sent_syn(bool ipv6) override; | │ │ │ │ │ +| void received_synack(bool ipv6) override; | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_ABI_VERSION == 1 | │ │ │ │ │ +| int m_peak_up_rate = 0; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| void on_tick(error_code const& e); | │ │ │ │ │ +| | │ │ │ │ │ +| void try_connect_more_peers(); | │ │ │ │ │ +|_ _ _ _v_o_i_d_ _a_u_t_o___m_a_n_a_g_e___c_h_e_c_k_i_n_g___t_o_r_r_e_n_t_s_(_s_t_d_:_:_v_e_c_t_o_r_<_t_o_r_r_e_n_t_*_>_&_ _l_i_s_t_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|relevance 0|_._._/_i_n_c_l_u_d_e_/_l_i_b_t_o_r_r_e_n_t_/_a_u_x___/ |it would be nice to not have this be part of session_interface | │ │ │ │ │ +|_ _ _ _ _ _ _ _ _ _ _ _|_s_e_s_s_i_o_n___i_n_t_e_r_f_a_c_e_._h_p_p_:_2_1_2_ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | │ │ │ │ │ +|********** iitt wwoouulldd bbee nniiccee ttoo nnoott hhaavvee tthhiiss bbee ppaarrtt ooff sseessssiioonn__iinntteerrffaaccee ********** | │ │ │ │ │ +|****** ....//iinncclluuddee//lliibbttoorrrreenntt//aauuxx__//sseessssiioonn__iinntteerrffaaccee..hhpppp::221122 ****** | │ │ │ │ │ +|virtual void deferred_submit_jobs() = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual std::uint16_t listen_port() const = 0; | │ │ │ │ │ +| virtual std::uint16_t ssl_listen_port() const = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual int listen_port(aux::transport ssl, address const& local_addr) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual void for_each_listen_socket(std::function f) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // ask for which interface and port to bind outgoing peer connections on | │ │ │ │ │ +| virtual tcp::endpoint bind_outgoing_socket(socket_type& s, address const& | │ │ │ │ │ +| remote_address, error_code& ec) const = 0; | │ │ │ │ │ +| virtual bool verify_bound_address(address const& addr, bool utp | │ │ │ │ │ +| , error_code& ec) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +|#ifndef TORRENT_DISABLE_MUTABLE_TORRENTS | │ │ │ │ │ +| virtual std::vector> find_collection( | │ │ │ │ │ +| std::string const& collection) const = 0; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +|virtual proxy_settings proxy() const = 0; | │ │ │ │ │ +| | │ │ │ │ │ +|#if TORRENT_USE_I2P | │ │ │ │ │ +| virtual char const* i2p_session() const = 0; | │ │ │ │ │ +| virtual std::string const& local_i2p_endpoint() const = 0; | │ │ │ │ │ +|#endif | │ │ │ │ │ +| | │ │ │ │ │ +| virtual void prioritize_connections(std::weak_ptr t) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual void trigger_auto_manage() = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual void apply_settings_pack(std::shared_ptr pack) = 0; | │ │ │ │ │ +| virtual session_settings const& settings() const = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual void queue_tracker_request(tracker_request req | │ │ │ │ │ +| , std::weak_ptr c) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| // peer-classes | │ │ │ │ │ +| virtual void set_peer_classes(peer_class_set* s, address const& a, socket_type_t st) = 0; | │ │ │ │ │ +| virtual peer_class_pool const& peer_classes() const = 0; | │ │ │ │ │ +| virtual peer_class_pool& peer_classes() = 0; | │ │ │ │ │ +| virtual bool ignore_unchoke_slots_set(peer_class_set const& set) const = 0; | │ │ │ │ │ +| virtual int copy_pertinent_channels(peer_class_set const& set | │ │ │ │ │ +| , int channel, bandwidth_channel** dst, int m) = 0; | │ │ │ │ │ +| virtual int use_quota_overhead(peer_class_set& set, int amount_down, int amount_up) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual bandwidth_manager* get_bandwidth_manager(int channel) = 0; | │ │ │ │ │ +| | │ │ │ │ │ +| virtual void sent_bytes(int bytes_payload, int bytes_protocol) = 0; | │ │ │ │ │ +| virtual void received_bytes(int bytes_payload, int bytes_protocol) = 0; | │ │ │ │ │ +|_ _ _v_i_r_t_u_a_l_ _v_o_i_d_ _t_r_a_n_c_i_e_v_e___i_p___p_a_c_k_e_t_(_i_n_t_ _b_y_t_e_s_,_ _b_o_o_l_ _i_p_v_6_)_ _=_ _0_;_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |