diff --git a/libtransmission/announcer-udp.cc b/libtransmission/announcer-udp.cc index 2aade4a62..28d613d57 100644 --- a/libtransmission/announcer-udp.cc +++ b/libtransmission/announcer-udp.cc @@ -50,6 +50,7 @@ using tau_connection_t = uint64_t; using tau_transaction_t = uint32_t; using InBuf = libtransmission::BufferReader; +using PayloadBuffer = libtransmission::Buffer; constexpr auto TauConnectionTtlSecs = time_t{ 45 }; @@ -85,7 +86,7 @@ struct tau_scrape_request } // build the payload - auto buf = libtransmission::Buffer{}; + auto buf = PayloadBuffer{}; buf.add_uint32(TAU_ACTION_SCRAPE); buf.add_uint32(transaction_id); for (int i = 0; i < in.info_hash_count; ++i) @@ -179,7 +180,7 @@ struct tau_announce_request response.info_hash = in.info_hash; // build the payload - auto buf = libtransmission::Buffer{}; + auto buf = PayloadBuffer{}; buf.add_uint32(TAU_ACTION_ANNOUNCE); buf.add_uint32(transaction_id); buf.add(in.info_hash); @@ -374,7 +375,7 @@ struct tau_tracker this->connection_transaction_id = tau_transaction_new(); logtrace(this->key, fmt::format("Trying to connect. Transaction ID is {}", this->connection_transaction_id)); - auto buf = libtransmission::Buffer{}; + auto buf = PayloadBuffer{}; buf.add_uint64(0x41727101980LL); buf.add_uint32(TAU_ACTION_CONNECT); buf.add_uint32(this->connection_transaction_id); @@ -462,7 +463,7 @@ private: { if (this->connecting_at != 0 && this->connecting_at + ConnectionRequestTtl < now) { - auto empty_buf = libtransmission::Buffer{}; + auto empty_buf = PayloadBuffer{}; on_connection_response(TAU_ACTION_ERROR, empty_buf); } @@ -535,7 +536,7 @@ private: { logdbg(this->key, fmt::format("sending request w/connection id {}", this->connection_id)); - auto buf = libtransmission::Buffer{}; + auto buf = PayloadBuffer{}; buf.add_uint64(this->connection_id); buf.add(payload, payload_len); @@ -622,7 +623,7 @@ public: } // extract the action_id and see if it makes sense - auto buf = libtransmission::Buffer{}; + auto buf = PayloadBuffer{}; buf.add(msg, msglen); auto const action_id = static_cast(buf.to_uint32()); diff --git a/libtransmission/peer-io.cc b/libtransmission/peer-io.cc index f5cd7e0b6..c4c3d10f9 100644 --- a/libtransmission/peer-io.cc +++ b/libtransmission/peer-io.cc @@ -419,7 +419,7 @@ size_t tr_peerIo::try_read(size_t max) auto& buf = inbuf_; tr_error* error = nullptr; - auto const n_read = socket_.try_read(buf, max, &error); + auto const n_read = socket_.try_read(buf, max, std::empty(buf), &error); set_enabled(Dir, error == nullptr || canRetryFromError(error->code)); if (error != nullptr) diff --git a/libtransmission/peer-io.h b/libtransmission/peer-io.h index 5580e860b..215634bd7 100644 --- a/libtransmission/peer-io.h +++ b/libtransmission/peer-io.h @@ -15,6 +15,8 @@ #include #include // std::pair +#include // for evutil_socket_t + #include "transmission.h" #include "bandwidth.h" @@ -289,8 +291,11 @@ public: static void utp_init(struct_utp_context* ctx); private: + // our target socket receive buffer size static constexpr auto RcvBuf = size_t{ 256 * 1024 }; + using PeerBuffer = libtransmission::Buffer; + friend class libtransmission::test::HandshakeTest; [[nodiscard]] constexpr auto is_seed() const noexcept @@ -342,8 +347,8 @@ private: tr_sha1_digest_t info_hash_; - libtransmission::Buffer inbuf_; - libtransmission::Buffer outbuf_; + PeerBuffer inbuf_; + PeerBuffer outbuf_; tr_session* const session_; diff --git a/libtransmission/peer-mgr-active-requests.cc b/libtransmission/peer-mgr-active-requests.cc index c6535079e..d21d3f286 100644 --- a/libtransmission/peer-mgr-active-requests.cc +++ b/libtransmission/peer-mgr-active-requests.cc @@ -11,53 +11,16 @@ #include #include +#include + #define LIBTRANSMISSION_PEER_MODULE #include "libtransmission/transmission.h" #include "libtransmission/peer-mgr-active-requests.h" +#include "libtransmission/peer-mgr-wishlist.h" #include "libtransmission/tr-assert.h" -namespace -{ - -struct peer_at -{ - tr_peer* peer; - time_t when; - - peer_at(tr_peer* p, time_t w) - : peer{ p } - , when{ w } - { - } - - [[nodiscard]] int compare(peer_at const& that) const // <=> - { - if (peer != that.peer) - { - return peer < that.peer ? -1 : 1; - } - - return 0; - } - - bool operator==(peer_at const& that) const - { - return compare(that) == 0; - } -}; - -struct PeerAtHash -{ - std::size_t operator()(peer_at const& pa) const noexcept - { - return std::hash{}(pa.peer); - } -}; - -} // namespace - class ActiveRequests::Impl { public: @@ -97,7 +60,7 @@ public: std::unordered_map count_; - std::unordered_map> blocks_; + std::unordered_map> blocks_; private: size_t size_ = 0; @@ -126,8 +89,7 @@ bool ActiveRequests::add(tr_block_index_t block, tr_peer* peer, time_t when) bool ActiveRequests::remove(tr_block_index_t block, tr_peer const* peer) { auto const it = impl_->blocks_.find(block); - auto const key = peer_at{ const_cast(peer), 0 }; - auto const removed = it != std::end(impl_->blocks_) && it->second.erase(key) != 0; + auto const removed = it != std::end(impl_->blocks_) && it->second.erase(peer) != 0; if (removed) { @@ -148,10 +110,9 @@ std::vector ActiveRequests::remove(tr_peer const* peer) auto removed = std::vector{}; removed.reserve(impl_->blocks_.size()); - auto const key = peer_at{ const_cast(peer), 0 }; for (auto const& [block, peers_at] : impl_->blocks_) { - if (peers_at.count(key) != 0U) + if (peers_at.count(peer) != 0U) { removed.push_back(block); } @@ -178,7 +139,7 @@ std::vector ActiveRequests::remove(tr_block_index_t block) std::begin(it->second), std::end(it->second), std::begin(removed), - [](auto const& sent) { return sent.peer; }); + [](auto const& iter) { return const_cast(iter.first); }); impl_->blocks_.erase(block); } @@ -193,8 +154,8 @@ std::vector ActiveRequests::remove(tr_block_index_t block) // return true if there's an active request to `peer` for `block` bool ActiveRequests::has(tr_block_index_t block, tr_peer const* peer) const { - auto const it = impl_->blocks_.find(block); - return it != std::end(impl_->blocks_) && (it->second.count(peer_at{ const_cast(peer), 0 }) != 0U); + auto const iter = impl_->blocks_.find(block); + return iter != std::end(impl_->blocks_) && (iter->second.count(peer) != 0U); } // count how many peers we're asking for `block` @@ -225,11 +186,11 @@ std::vector> ActiveRequests::sentBefore(ti for (auto const& [block, peers_at] : impl_->blocks_) { - for (auto const& sent : peers_at) + for (auto const& [peer, sent_at] : peers_at) { - if (sent.when < when) + if (sent_at < when) { - sent_before.emplace_back(block, sent.peer); + sent_before.emplace_back(block, const_cast(peer)); } } } diff --git a/libtransmission/peer-mgr-wishlist.h b/libtransmission/peer-mgr-wishlist.h index c99ac0eab..dcb8d9e75 100644 --- a/libtransmission/peer-mgr-wishlist.h +++ b/libtransmission/peer-mgr-wishlist.h @@ -22,6 +22,8 @@ class Wishlist { public: + static auto constexpr EndgameMaxPeers = size_t{ 2U }; + struct Mediator { [[nodiscard]] virtual bool clientCanRequestBlock(tr_block_index_t block) const = 0; diff --git a/libtransmission/peer-socket.cc b/libtransmission/peer-socket.cc index 60f59b451..52daa78c2 100644 --- a/libtransmission/peer-socket.cc +++ b/libtransmission/peer-socket.cc @@ -70,7 +70,7 @@ void tr_peer_socket::close() handle = {}; } -size_t tr_peer_socket::try_write(Buffer& buf, size_t max, tr_error** error) const +size_t tr_peer_socket::try_write(OutBuf& buf, size_t max, tr_error** error) const { if (max == size_t{}) { @@ -107,7 +107,7 @@ size_t tr_peer_socket::try_write(Buffer& buf, size_t max, tr_error** error) cons return {}; } -size_t tr_peer_socket::try_read(Buffer& buf, size_t max, tr_error** error) const +size_t tr_peer_socket::try_read(InBuf& buf, size_t max, [[maybe_unused]] bool buf_is_empty, tr_error** error) const { if (max == size_t{}) { @@ -123,7 +123,7 @@ size_t tr_peer_socket::try_read(Buffer& buf, size_t max, tr_error** error) const // utp_read_drained() notifies libutp that this read buffer is empty. // It opens up the congestion window by sending an ACK (soonish) if // one was not going to be sent. - if (is_utp() && std::empty(buf)) + if (is_utp() && buf_is_empty) { utp_read_drained(handle.utp); } diff --git a/libtransmission/peer-socket.h b/libtransmission/peer-socket.h index f57ab7ad4..32c32840e 100644 --- a/libtransmission/peer-socket.h +++ b/libtransmission/peer-socket.h @@ -27,7 +27,8 @@ struct tr_session; class tr_peer_socket { public: - using Buffer = libtransmission::Buffer; + using InBuf = libtransmission::BufferWriter; + using OutBuf = libtransmission::BufferReader; tr_peer_socket() = default; tr_peer_socket(tr_session const* session, tr_address const& address, tr_port port, tr_socket_t sock); @@ -56,8 +57,8 @@ public: } void close(); - size_t try_write(Buffer& buf, size_t max, tr_error** error) const; - size_t try_read(Buffer& buf, size_t max, tr_error** error) const; + size_t try_read(InBuf& buf, size_t max, bool buf_is_empty, tr_error** error) const; + size_t try_write(OutBuf& buf, size_t max, tr_error** error) const; [[nodiscard]] constexpr std::pair socketAddress() const noexcept { diff --git a/libtransmission/web.h b/libtransmission/web.h index d77509749..fb767e9fc 100644 --- a/libtransmission/web.h +++ b/libtransmission/web.h @@ -14,6 +14,8 @@ #include #include +#include + struct evbuffer; class tr_web