diff --git a/libtransmission/announcer-udp.cc b/libtransmission/announcer-udp.cc
index 5a32b48b7..affaba388 100644
--- a/libtransmission/announcer-udp.cc
+++ b/libtransmission/announcer-udp.cc
@@ -652,7 +652,7 @@ static void tau_tracker_upkeep_ex(struct tau_tracker* tracker, bool timeout_reqs
hints.ai_protocol = IPPROTO_UDP;
logtrace(tracker->host, "Trying a new DNS lookup");
tracker->dns_request = evdns_getaddrinfo(
- tracker->session->evdns_base,
+ tracker->session->evdnsBase(),
tr_strlower(tracker->host.sv()).c_str(),
nullptr,
&hints,
diff --git a/libtransmission/peer-mgr.cc b/libtransmission/peer-mgr.cc
index c40f792db..a504e5c7e 100644
--- a/libtransmission/peer-mgr.cc
+++ b/libtransmission/peer-mgr.cc
@@ -2219,7 +2219,7 @@ void rechokeUploads(tr_swarm* s, uint64_t const now)
for (auto& item : choked)
{
- if (unchoked_interested >= session->upload_slots_per_torrent)
+ if (unchoked_interested >= session->uploadSlotsPerTorrent())
{
break;
}
@@ -2813,7 +2813,7 @@ struct peer_candidate
void initiateConnection(tr_peerMgr* mgr, tr_swarm* s, peer_atom& atom)
{
time_t const now = tr_time();
- bool utp = tr_sessionIsUTPEnabled(mgr->session) && !atom.utp_failed;
+ bool utp = mgr->session->allowsUTP() && !atom.utp_failed;
if (atom.fromFirst == TR_PEER_FROM_PEX)
{
diff --git a/libtransmission/peer-msgs.cc b/libtransmission/peer-msgs.cc
index 8974d2168..f0cf1627e 100644
--- a/libtransmission/peer-msgs.cc
+++ b/libtransmission/peer-msgs.cc
@@ -1548,7 +1548,7 @@ static ReadState readBtId(tr_peerMsgsImpl* msgs, struct evbuffer* inbuf, size_t
static void prefetchPieces(tr_peerMsgsImpl* msgs)
{
- if (!msgs->session->isPrefetchEnabled)
+ if (!msgs->session->allowsPrefetch())
{
return;
}
diff --git a/libtransmission/rpc-server.cc b/libtransmission/rpc-server.cc
index 1044c48b0..64011ab49 100644
--- a/libtransmission/rpc-server.cc
+++ b/libtransmission/rpc-server.cc
@@ -105,15 +105,6 @@ static bool constexpr tr_rpc_address_is_valid(tr_rpc_address const& a)
}
#endif
-/***
-****
-***/
-
-static char const* get_current_session_id(tr_rpc_server const* server)
-{
- return server->session->session_id.c_str();
-}
-
/**
***
**/
@@ -398,10 +389,8 @@ static bool isHostnameAllowed(tr_rpc_server const* server, struct evhttp_request
static bool test_session_id(tr_rpc_server* server, evhttp_request const* req)
{
- char const* ours = get_current_session_id(server);
- char const* theirs = evhttp_find_header(req->input_headers, TR_RPC_SESSION_ID_HEADER);
- bool const success = theirs != nullptr && strcmp(theirs, ours) == 0;
- return success;
+ char const* const session_id = evhttp_find_header(req->input_headers, TR_RPC_SESSION_ID_HEADER);
+ return session_id != nullptr && server->session->sessionId() == session_id;
}
static bool isAuthorized(tr_rpc_server const* server, char const* auth_header)
@@ -518,7 +507,7 @@ static void handle_request(struct evhttp_request* req, void* arg)
#ifdef REQUIRE_SESSION_ID
else if (!test_session_id(server, req))
{
- char const* sessionId = get_current_session_id(server);
+ auto const session_id = std::string{ server->session->sessionId() };
auto const tmp = fmt::format(
FMT_STRING("
Your request had an invalid session-id header.
"
"To fix this, follow these steps:"
@@ -531,8 +520,8 @@ static void handle_request(struct evhttp_request* req, void* arg)
"attacks.
"
"{:s}: {:s}
"),
TR_RPC_SESSION_ID_HEADER,
- sessionId);
- evhttp_add_header(req->output_headers, TR_RPC_SESSION_ID_HEADER, sessionId);
+ session_id);
+ evhttp_add_header(req->output_headers, TR_RPC_SESSION_ID_HEADER, session_id.c_str());
evhttp_add_header(req->output_headers, "Access-Control-Expose-Headers", TR_RPC_SESSION_ID_HEADER);
send_simple_response(req, 409, tmp.c_str());
}
diff --git a/libtransmission/rpcimpl.cc b/libtransmission/rpcimpl.cc
index ad0d30a38..0b9a707f3 100644
--- a/libtransmission/rpcimpl.cc
+++ b/libtransmission/rpcimpl.cc
@@ -2188,7 +2188,7 @@ static void addSessionField(tr_session const* s, tr_variant* d, tr_quark key)
break;
case TR_KEY_utp_enabled:
- tr_variantDictAddBool(d, key, tr_sessionIsUTPEnabled(s));
+ tr_variantDictAddBool(d, key, s->allowsUTP());
break;
case TR_KEY_dht_enabled:
@@ -2232,11 +2232,11 @@ static void addSessionField(tr_session const* s, tr_variant* d, tr_quark key)
break;
case TR_KEY_seedRatioLimited:
- tr_variantDictAddBool(d, key, tr_sessionIsRatioLimited(s));
+ tr_variantDictAddBool(d, key, s->isRatioLimited());
break;
case TR_KEY_idle_seeding_limit:
- tr_variantDictAddInt(d, key, tr_sessionGetIdleLimit(s));
+ tr_variantDictAddInt(d, key, s->idleLimitMinutes());
break;
case TR_KEY_idle_seeding_limit_enabled:
@@ -2264,7 +2264,7 @@ static void addSessionField(tr_session const* s, tr_variant* d, tr_quark key)
break;
case TR_KEY_speed_limit_up_enabled:
- tr_variantDictAddBool(d, key, tr_sessionIsSpeedLimited(s, TR_UP));
+ tr_variantDictAddBool(d, key, s->isSpeedLimited(TR_UP));
break;
case TR_KEY_speed_limit_down:
@@ -2272,7 +2272,7 @@ static void addSessionField(tr_session const* s, tr_variant* d, tr_quark key)
break;
case TR_KEY_speed_limit_down_enabled:
- tr_variantDictAddBool(d, key, tr_sessionIsSpeedLimited(s, TR_DOWN));
+ tr_variantDictAddBool(d, key, s->isSpeedLimited(TR_DOWN));
break;
case TR_KEY_script_torrent_added_filename:
@@ -2328,7 +2328,7 @@ static void addSessionField(tr_session const* s, tr_variant* d, tr_quark key)
break;
case TR_KEY_session_id:
- tr_variantDictAddStr(d, key, s->session_id.sv());
+ tr_variantDictAddStr(d, key, s->sessionId());
break;
}
}
diff --git a/libtransmission/session.cc b/libtransmission/session.cc
index c45518320..a98f15477 100644
--- a/libtransmission/session.cc
+++ b/libtransmission/session.cc
@@ -25,6 +25,7 @@
#include /* umask() */
#endif
+#include
#include
#include
@@ -389,17 +390,17 @@ void tr_sessionGetSettings(tr_session const* s, tr_variant* setme_dictionary)
tr_variantDictAddStr(d, TR_KEY_blocklist_url, s->blocklistUrl());
tr_variantDictAddInt(d, TR_KEY_cache_size_mb, tr_sessionGetCacheLimit_MB(s));
tr_variantDictAddBool(d, TR_KEY_dht_enabled, s->allowsDHT());
- tr_variantDictAddBool(d, TR_KEY_utp_enabled, s->isUTPEnabled);
+ tr_variantDictAddBool(d, TR_KEY_utp_enabled, s->allowsUTP());
tr_variantDictAddBool(d, TR_KEY_lpd_enabled, s->allowsLPD());
tr_variantDictAddStr(d, TR_KEY_download_dir, tr_sessionGetDownloadDir(s));
tr_variantDictAddStr(d, TR_KEY_default_trackers, s->defaultTrackersStr());
tr_variantDictAddInt(d, TR_KEY_download_queue_size, s->queueSize(TR_DOWN));
tr_variantDictAddBool(d, TR_KEY_download_queue_enabled, s->queueEnabled(TR_DOWN));
tr_variantDictAddInt(d, TR_KEY_speed_limit_down, tr_sessionGetSpeedLimit_KBps(s, TR_DOWN));
- tr_variantDictAddBool(d, TR_KEY_speed_limit_down_enabled, tr_sessionIsSpeedLimited(s, TR_DOWN));
+ tr_variantDictAddBool(d, TR_KEY_speed_limit_down_enabled, s->isSpeedLimited(TR_DOWN));
tr_variantDictAddInt(d, TR_KEY_encryption, s->encryptionMode());
- tr_variantDictAddInt(d, TR_KEY_idle_seeding_limit, tr_sessionGetIdleLimit(s));
- tr_variantDictAddBool(d, TR_KEY_idle_seeding_limit_enabled, tr_sessionIsIdleLimited(s));
+ tr_variantDictAddInt(d, TR_KEY_idle_seeding_limit, s->idleLimitMinutes());
+ tr_variantDictAddBool(d, TR_KEY_idle_seeding_limit_enabled, s->isIdleLimited());
tr_variantDictAddStr(d, TR_KEY_incomplete_dir, tr_sessionGetIncompleteDir(s));
tr_variantDictAddBool(d, TR_KEY_incomplete_dir_enabled, tr_sessionIsIncompleteDirEnabled(s));
tr_variantDictAddInt(d, TR_KEY_message_level, tr_logGetLevel());
@@ -414,12 +415,12 @@ void tr_sessionGetSettings(tr_session const* s, tr_variant* setme_dictionary)
tr_variantDictAddBool(d, TR_KEY_pex_enabled, s->allowsPEX());
tr_variantDictAddBool(d, TR_KEY_port_forwarding_enabled, tr_sessionIsPortForwardingEnabled(s));
tr_variantDictAddInt(d, TR_KEY_preallocation, s->preallocationMode());
- tr_variantDictAddBool(d, TR_KEY_prefetch_enabled, s->isPrefetchEnabled);
- tr_variantDictAddInt(d, TR_KEY_peer_id_ttl_hours, s->peer_id_ttl_hours);
+ tr_variantDictAddBool(d, TR_KEY_prefetch_enabled, s->allowsPrefetch());
+ tr_variantDictAddInt(d, TR_KEY_peer_id_ttl_hours, s->peerIdTTLHours());
tr_variantDictAddBool(d, TR_KEY_queue_stalled_enabled, s->queueStalledEnabled());
tr_variantDictAddInt(d, TR_KEY_queue_stalled_minutes, s->queueStalledMinutes());
tr_variantDictAddReal(d, TR_KEY_ratio_limit, s->desiredRatio());
- tr_variantDictAddBool(d, TR_KEY_ratio_limit_enabled, s->isRatioLimited);
+ tr_variantDictAddBool(d, TR_KEY_ratio_limit_enabled, s->isRatioLimited());
tr_variantDictAddBool(d, TR_KEY_rename_partial_files, s->isIncompleteFileNamingEnabled());
tr_variantDictAddBool(d, TR_KEY_rpc_authentication_required, tr_sessionIsRPCPasswordEnabled(s));
tr_variantDictAddStr(d, TR_KEY_rpc_bind_address, s->rpc_server_->getBindAddress());
@@ -442,9 +443,9 @@ void tr_sessionGetSettings(tr_session const* s, tr_variant* setme_dictionary)
tr_variantDictAddInt(d, TR_KEY_alt_speed_time_end, tr_sessionGetAltSpeedEnd(s));
tr_variantDictAddInt(d, TR_KEY_alt_speed_time_day, tr_sessionGetAltSpeedDay(s));
tr_variantDictAddInt(d, TR_KEY_speed_limit_up, tr_sessionGetSpeedLimit_KBps(s, TR_UP));
- tr_variantDictAddBool(d, TR_KEY_speed_limit_up_enabled, tr_sessionIsSpeedLimited(s, TR_UP));
- tr_variantDictAddStr(d, TR_KEY_umask, fmt::format("{:#o}", s->umask));
- tr_variantDictAddInt(d, TR_KEY_upload_slots_per_torrent, s->upload_slots_per_torrent);
+ tr_variantDictAddBool(d, TR_KEY_speed_limit_up_enabled, s->isSpeedLimited(TR_UP));
+ tr_variantDictAddStr(d, TR_KEY_umask, fmt::format("{:#o}", s->umask_));
+ tr_variantDictAddInt(d, TR_KEY_upload_slots_per_torrent, s->uploadSlotsPerTorrent());
tr_variantDictAddStr(d, TR_KEY_bind_address_ipv4, s->bind_ipv4.readable());
tr_variantDictAddStr(d, TR_KEY_bind_address_ipv6, s->bind_ipv6.readable());
tr_variantDictAddBool(d, TR_KEY_start_added_torrents, !s->shouldPauseAddedTorrents());
@@ -646,8 +647,6 @@ void tr_session::onNowTimer()
now_timer_->setInterval(std::chrono::duration_cast(target_interval));
}
-static void loadBlocklists(tr_session* session);
-
void tr_session::initImpl(init_data& data)
{
auto lock = unique_lock();
@@ -679,7 +678,7 @@ void tr_session::initImpl(init_data& data)
**/
tr_sys_dir_create(tr_pathbuf{ configDir(), "/blocklists"sv }, TR_SYS_DIR_CREATE_PARENTS, 0777);
- loadBlocklists(this);
+ loadBlocklists();
tr_announcerInit(this);
@@ -728,14 +727,14 @@ void tr_session::setImpl(init_data& data)
if (tr_variantDictFindStrView(settings, TR_KEY_umask, &sv))
{
/* Read a umask as a string representing an octal number. */
- this->umask = static_cast(tr_parseNum(sv, 8).value_or(DefaultUmask));
- ::umask(this->umask);
+ this->umask_ = static_cast(tr_parseNum(sv, 8).value_or(DefaultUmask));
+ ::umask(this->umask_);
}
else if (tr_variantDictFindInt(settings, TR_KEY_umask, &i))
{
/* Or as a base 10 integer to remain compatible with the old settings format. */
- this->umask = (mode_t)i;
- ::umask(this->umask);
+ this->umask_ = (mode_t)i;
+ ::umask(this->umask_);
}
#endif
@@ -819,7 +818,7 @@ void tr_session::setImpl(init_data& data)
if (tr_variantDictFindInt(settings, TR_KEY_peer_id_ttl_hours, &i))
{
- this->peer_id_ttl_hours = i;
+ this->peer_id_ttl_hours_ = i;
}
/* torrent queues */
@@ -856,7 +855,7 @@ void tr_session::setImpl(init_data& data)
/* files and directories */
if (tr_variantDictFindBool(settings, TR_KEY_prefetch_enabled, &boolVal))
{
- this->isPrefetchEnabled = boolVal;
+ this->is_prefetch_enabled_ = boolVal;
}
if (tr_variantDictFindInt(settings, TR_KEY_preallocation, &i))
@@ -957,7 +956,7 @@ void tr_session::setImpl(init_data& data)
if (tr_variantDictFindInt(settings, TR_KEY_upload_slots_per_torrent, &i))
{
- this->upload_slots_per_torrent = i;
+ this->upload_slots_per_torrent_ = i;
}
if (tr_variantDictFindInt(settings, TR_KEY_speed_limit_up, &i))
@@ -1255,11 +1254,11 @@ tr_port_forwarding tr_sessionGetPortForwarding(tr_session const* session)
****
***/
-void tr_sessionSetRatioLimited(tr_session* session, bool isLimited)
+void tr_sessionSetRatioLimited(tr_session* session, bool is_limited)
{
TR_ASSERT(session != nullptr);
- session->isRatioLimited = isLimited;
+ session->is_ratio_limited_ = is_limited;
}
void tr_sessionSetRatioLimit(tr_session* session, double desired_ratio)
@@ -1273,7 +1272,7 @@ bool tr_sessionIsRatioLimited(tr_session const* session)
{
TR_ASSERT(session != nullptr);
- return session->isRatioLimited;
+ return session->isRatioLimited();
}
double tr_sessionGetRatioLimit(tr_session const* session)
@@ -1294,11 +1293,11 @@ void tr_sessionSetIdleLimited(tr_session* session, bool is_limited)
session->is_idle_limited_ = is_limited;
}
-void tr_sessionSetIdleLimit(tr_session* session, uint16_t idleMinutes)
+void tr_sessionSetIdleLimit(tr_session* session, uint16_t idle_minutes)
{
TR_ASSERT(session != nullptr);
- session->idleLimitMinutes = idleMinutes;
+ session->idle_limit_minutes_ = idle_minutes;
}
bool tr_sessionIsIdleLimited(tr_session const* session)
@@ -1312,7 +1311,7 @@ uint16_t tr_sessionGetIdleLimit(tr_session const* session)
{
TR_ASSERT(session != nullptr);
- return session->idleLimitMinutes;
+ return session->idleLimitMinutes();
}
/***
@@ -1330,7 +1329,7 @@ std::optional tr_session::activeSpeedLimitBps(tr_direction dir) co
return tr_sessionGetAltSpeed_Bps(this, dir);
}
- if (tr_sessionIsSpeedLimited(this, dir))
+ if (this->isSpeedLimited(dir))
{
return speedLimitBps(dir);
}
@@ -1471,19 +1470,19 @@ static void turtleBootstrap(tr_session* session, struct tr_turtle_info* turtle)
**** Primary session speed limits
***/
-static void tr_sessionSetSpeedLimit_Bps(tr_session* s, tr_direction d, unsigned int Bps)
+void tr_sessionSetSpeedLimit_Bps(tr_session* session, tr_direction dir, unsigned int Bps)
{
- TR_ASSERT(s != nullptr);
- TR_ASSERT(tr_isDirection(d));
+ TR_ASSERT(session != nullptr);
+ TR_ASSERT(tr_isDirection(dir));
- s->speedLimit_Bps[d] = Bps;
+ session->speed_limit_Bps_[dir] = Bps;
- updateBandwidth(s, d);
+ updateBandwidth(session, dir);
}
-void tr_sessionSetSpeedLimit_KBps(tr_session* s, tr_direction d, unsigned int KBps)
+void tr_sessionSetSpeedLimit_KBps(tr_session* session, tr_direction dir, unsigned int KBps)
{
- tr_sessionSetSpeedLimit_Bps(s, d, tr_toSpeedBytes(KBps));
+ tr_sessionSetSpeedLimit_Bps(session, dir, tr_toSpeedBytes(KBps));
}
unsigned int tr_sessionGetSpeedLimit_KBps(tr_session const* s, tr_direction d)
@@ -1491,22 +1490,22 @@ unsigned int tr_sessionGetSpeedLimit_KBps(tr_session const* s, tr_direction d)
return tr_toSpeedKBps(s->speedLimitBps(d));
}
-void tr_sessionLimitSpeed(tr_session* s, tr_direction d, bool b)
+void tr_sessionLimitSpeed(tr_session* session, tr_direction dir, bool limited)
{
- TR_ASSERT(s != nullptr);
- TR_ASSERT(tr_isDirection(d));
+ TR_ASSERT(session != nullptr);
+ TR_ASSERT(tr_isDirection(dir));
- s->speedLimitEnabled[d] = b;
+ session->speed_limit_enabled_[dir] = limited;
- updateBandwidth(s, d);
+ updateBandwidth(session, dir);
}
-bool tr_sessionIsSpeedLimited(tr_session const* s, tr_direction d)
+bool tr_sessionIsSpeedLimited(tr_session const* session, tr_direction dir)
{
- TR_ASSERT(s != nullptr);
- TR_ASSERT(tr_isDirection(d));
+ TR_ASSERT(session != nullptr);
+ TR_ASSERT(tr_isDirection(dir));
- return s->speedLimitEnabled[d];
+ return session->isSpeedLimited(dir);
}
/***
@@ -1733,8 +1732,6 @@ double tr_sessionGetRawSpeed_KBps(tr_session const* session, tr_direction dir)
return tr_toSpeedKBps(tr_sessionGetRawSpeed_Bps(session, dir));
}
-static void closeBlocklists(tr_session* /*session*/);
-
void tr_session::closeImplStart()
{
is_closing_ = true;
@@ -1818,7 +1815,7 @@ void tr_session::closeImplFinish()
stats().saveIfDirty();
tr_peerMgrFree(peerMgr);
tr_utpClose(this);
- closeBlocklists(this);
+ blocklists_.clear();
openFiles().closeAll();
is_closed_ = true;
}
@@ -2030,39 +2027,40 @@ void tr_sessionSetDHTEnabled(tr_session* session, bool enabled)
****
***/
-bool tr_sessionIsUTPEnabled(tr_session const* session)
+bool tr_session::allowsUTP() const noexcept
{
- TR_ASSERT(session != nullptr);
-
#ifdef WITH_UTP
- return session->isUTPEnabled;
+ return is_utp_enabled_;
#else
return false;
#endif
}
-static void toggle_utp(tr_session* const session)
+bool tr_sessionIsUTPEnabled(tr_session const* session)
{
TR_ASSERT(session != nullptr);
- session->isUTPEnabled = !session->isUTPEnabled;
-
- tr_udpSetSocketBuffers(session);
-
- tr_udpSetSocketTOS(session);
-
- /* But don't call tr_utpClose -- see reset_timer in tr-utp.c for an
- explanation. */
+ return session->allowsUTP();
}
void tr_sessionSetUTPEnabled(tr_session* session, bool enabled)
{
TR_ASSERT(session != nullptr);
- if (enabled != session->isUTPEnabled)
+ if (enabled == session->allowsUTP())
{
- tr_runInEventThread(session, toggle_utp, session);
+ return;
}
+ tr_runInEventThread(
+ session,
+ [session, enabled]()
+ {
+ session->is_utp_enabled_ = enabled;
+ tr_udpSetSocketBuffers(session);
+ tr_udpSetSocketTOS(session);
+ // But don't call tr_utpClose --
+ // see reset_timer in tr-utp.c for an explanation.
+ });
}
/***
@@ -2192,13 +2190,13 @@ bool tr_sessionIsPortForwardingEnabled(tr_session const* session)
****
***/
-static void loadBlocklists(tr_session* session)
+void tr_session::loadBlocklists()
{
auto loadme = std::unordered_set{};
- auto const is_enabled = session->useBlocklist();
+ auto const is_enabled = useBlocklist();
/* walk the blocklist directory... */
- auto const dirname = tr_pathbuf{ session->configDir(), "/blocklists"sv };
+ auto const dirname = tr_pathbuf{ configDir(), "/blocklists"sv };
auto const odir = tr_sys_dir_open(dirname);
if (odir == TR_BAD_SYS_DIR)
@@ -2261,26 +2259,39 @@ static void loadBlocklists(tr_session* session)
}
}
- session->blocklists.clear();
+ blocklists_.clear();
std::transform(
std::begin(loadme),
std::end(loadme),
- std::back_inserter(session->blocklists),
+ std::back_inserter(blocklists_),
[&is_enabled](auto const& path) { return std::make_unique(path.c_str(), is_enabled); });
/* cleanup */
tr_sys_dir_close(odir);
}
-static void closeBlocklists(tr_session* session)
+void tr_session::useBlocklist(bool enabled)
{
- session->blocklists.clear();
+ this->blocklist_enabled_ = enabled;
+
+ std::for_each(
+ std::begin(blocklists_),
+ std::end(blocklists_),
+ [enabled](auto& blocklist) { blocklist->setEnabled(enabled); });
+}
+
+bool tr_session::addressIsBlocked(tr_address const& addr) const noexcept
+{
+ return std::any_of(
+ std::begin(blocklists_),
+ std::end(blocklists_),
+ [&addr](auto& blocklist) { return blocklist->hasAddress(addr); });
}
void tr_sessionReloadBlocklists(tr_session* session)
{
- closeBlocklists(session);
- loadBlocklists(session);
+ session->blocklists_.clear();
+ session->loadBlocklists();
tr_peerMgrOnBlocklistChanged(session->peerMgr);
}
@@ -2289,7 +2300,7 @@ size_t tr_blocklistGetRuleCount(tr_session const* session)
{
TR_ASSERT(session != nullptr);
- auto& src = session->blocklists;
+ auto& src = session->blocklists_;
return std::accumulate(std::begin(src), std::end(src), 0, [](int sum, auto& cur) { return sum + cur->getRuleCount(); });
}
@@ -2300,13 +2311,6 @@ bool tr_blocklistIsEnabled(tr_session const* session)
return session->useBlocklist();
}
-void tr_session::useBlocklist(bool enabled)
-{
- this->blocklist_enabled_ = enabled;
-
- std::for_each(std::begin(blocklists), std::end(blocklists), [enabled](auto& blocklist) { blocklist->setEnabled(enabled); });
-}
-
void tr_blocklistSetEnabled(tr_session* session, bool enabled)
{
TR_ASSERT(session != nullptr);
@@ -2318,15 +2322,15 @@ bool tr_blocklistExists(tr_session const* session)
{
TR_ASSERT(session != nullptr);
- return !std::empty(session->blocklists);
+ return !std::empty(session->blocklists_);
}
-size_t tr_blocklistSetContent(tr_session* session, char const* contentFilename)
+size_t tr_blocklistSetContent(tr_session* session, char const* content_filename)
{
auto const lock = session->unique_lock();
// find (or add) the default blocklist
- auto& src = session->blocklists;
+ auto& src = session->blocklists_;
char const* const name = DEFAULT_BLOCKLIST_FILENAME;
auto const it = std::find_if(
std::begin(src),
@@ -2346,16 +2350,8 @@ size_t tr_blocklistSetContent(tr_session* session, char const* contentFilename)
}
// set the default blocklist's content
- int const ruleCount = b->setContent(contentFilename);
- return ruleCount;
-}
-
-bool tr_session::addressIsBlocked(tr_address const& addr) const noexcept
-{
- return std::any_of(
- std::begin(blocklists),
- std::end(blocklists),
- [&addr](auto& blocklist) { return blocklist->hasAddress(addr); });
+ auto const rule_count = b->setContent(content_filename);
+ return rule_count;
}
void tr_blocklistSetURL(tr_session* session, char const* url)
@@ -2876,8 +2872,14 @@ auto makeEventBase()
} // namespace
tr_session::tr_session(std::string_view config_dir)
- : session_id{ tr_time }
+ : session_id_{ tr_time }
, event_base_{ makeEventBase() }
+ , evdns_base_{ evdns_base_new(eventBase(), EVDNS_BASE_INITIALIZE_NAMESERVERS),
+ [](evdns_base* dns)
+ {
+ // if zero, active requests will be aborted
+ evdns_base_free(dns, 0);
+ } }
, timer_maker_{ std::make_unique(eventBase()) }
, config_dir_{ config_dir }
, resume_dir_{ makeResumeDir(config_dir) }
diff --git a/libtransmission/session.h b/libtransmission/session.h
index 86c448665..2bda4cf4a 100644
--- a/libtransmission/session.h
+++ b/libtransmission/session.h
@@ -130,11 +130,21 @@ struct tr_session
public:
explicit tr_session(std::string_view config_dir);
+ [[nodiscard]] std::string_view sessionId() const noexcept
+ {
+ return session_id_.sv();
+ }
+
[[nodiscard]] event_base* eventBase() noexcept
{
return event_base_.get();
}
+ [[nodiscard]] evdns_base* evdnsBase() noexcept
+ {
+ return evdns_base_.get();
+ }
+
[[nodiscard]] auto& timerMaker() noexcept
{
return *timer_maker_;
@@ -460,24 +470,10 @@ public:
TR_SCRIPT_ON_TORRENT_DONE_SEEDING } }
};
- bool isUTPEnabled = false;
- bool isPrefetchEnabled = false;
- bool isRatioLimited = false;
-
- uint8_t peer_id_ttl_hours = 0;
-
- int umask = 0;
-
- unsigned int speedLimit_Bps[2] = { 0, 0 };
- bool speedLimitEnabled[2] = { false, false };
-
struct tr_turtle_info turtle;
- struct evdns_base* evdns_base = nullptr;
struct tr_event_handle* events = nullptr;
- uint16_t upload_slots_per_torrent = 0;
-
/* The UDP sockets used for the DHT and uTP. */
tr_port udp_port;
tr_socket_t udp_socket = TR_BAD_SOCKET;
@@ -510,37 +506,13 @@ public:
public_peer_port = port;
}
- std::vector> blocklists;
struct tr_peerMgr* peerMgr = nullptr;
struct tr_shared* shared = nullptr;
std::unique_ptr cache;
- class WebMediator final : public tr_web::Mediator
- {
- public:
- explicit WebMediator(tr_session* session)
- : session_{ session }
- {
- }
- ~WebMediator() override = default;
-
- [[nodiscard]] std::optional cookieFile() const override;
- [[nodiscard]] std::optional publicAddress() const override;
- [[nodiscard]] std::optional userAgent() const override;
- [[nodiscard]] unsigned int clamp(int torrent_id, unsigned int byte_count) const override;
- void notifyBandwidthConsumed(int torrent_id, size_t byte_count) override;
- // runs the tr_web::fetch response callback in the libtransmission thread
- void run(tr_web::FetchDoneFunc&& func, tr_web::FetchResponse&& response) const override;
-
- private:
- tr_session* const session_;
- };
-
std::unique_ptr web;
- tr_session_id session_id;
-
struct tr_announcer* announcer = nullptr;
struct tr_announcer_udp* announcer_udp = nullptr;
@@ -549,20 +521,11 @@ public:
std::vector>> bandwidth_groups_;
- uint16_t idleLimitMinutes;
-
tr_bindinfo bind_ipv4 = tr_bindinfo{ tr_inaddr_any };
tr_bindinfo bind_ipv6 = tr_bindinfo{ tr_in6addr_any };
std::unique_ptr rpc_server_;
- tr_announce_list default_trackers_;
-
- // One of 's IPTOS_ values.
- // See tr_netTos*() in libtransmission/net.h for more info
- // Only session.cc should use this.
- int peer_socket_tos_ = *tr_netTosFromName(TR_DEFAULT_PEER_SOCKET_TOS_STR);
-
[[nodiscard]] auto constexpr queueEnabled(tr_direction dir) const noexcept
{
return queue_enabled_[dir];
@@ -593,6 +556,11 @@ public:
return peer_limit_per_torrent_;
}
+ [[nodiscard]] auto constexpr uploadSlotsPerTorrent() const noexcept
+ {
+ return upload_slots_per_torrent_;
+ }
+
[[nodiscard]] auto constexpr isClosing() const noexcept
{
return is_closing_;
@@ -643,11 +611,23 @@ public:
return is_pex_enabled_;
}
+ [[nodiscard]] bool allowsUTP() const noexcept;
+
+ [[nodiscard]] auto constexpr allowsPrefetch() const noexcept
+ {
+ return is_prefetch_enabled_;
+ }
+
[[nodiscard]] auto constexpr isIdleLimited() const noexcept
{
return is_idle_limited_;
}
+ [[nodiscard]] auto constexpr idleLimitMinutes() const noexcept
+ {
+ return idle_limit_minutes_;
+ }
+
[[nodiscard]] std::vector getAllTorrents() const
{
return std::vector{ std::begin(torrents()), std::end(torrents()) };
@@ -681,7 +661,12 @@ public:
[[nodiscard]] constexpr auto speedLimitBps(tr_direction dir) const noexcept
{
- return speedLimit_Bps[dir];
+ return speed_limit_Bps_[dir];
+ }
+
+ [[nodiscard]] constexpr auto isSpeedLimited(tr_direction dir) const noexcept
+ {
+ return speed_limit_enabled_[dir];
}
[[nodiscard]] auto pieceSpeedBps(tr_direction dir) const noexcept
@@ -701,22 +686,40 @@ public:
return is_port_random_;
}
+ [[nodiscard]] auto constexpr isRatioLimited() const noexcept
+ {
+ return is_ratio_limited_;
+ }
+
[[nodiscard]] constexpr auto desiredRatio() const noexcept
{
return desired_ratio_;
}
+ [[nodiscard]] constexpr auto peerIdTTLHours() const noexcept
+ {
+ return peer_id_ttl_hours_;
+ }
+
private:
[[nodiscard]] tr_port randomPort() const;
+ void loadBlocklists();
+
+ friend bool tr_blocklistExists(tr_session const* session);
+ friend size_t tr_blocklistGetRuleCount(tr_session const* session);
+ friend size_t tr_blocklistSetContent(tr_session* session, char const* content_filename);
friend tr_session* tr_sessionInit(char const* config_dir, bool message_queueing_enabled, tr_variant* client_settings);
friend uint16_t tr_sessionSetPeerPortRandom(tr_session* session);
friend void tr_sessionClose(tr_session* session);
friend void tr_sessionGetSettings(tr_session const* s, tr_variant* setme_dictionary);
+ friend void tr_sessionLimitSpeed(tr_session* session, tr_direction dir, bool limited);
+ friend void tr_sessionReloadBlocklists(tr_session* session);
friend void tr_sessionSet(tr_session* session, tr_variant* settings);
friend void tr_sessionSetDHTEnabled(tr_session* session, bool enabled);
friend void tr_sessionSetDeleteSource(tr_session* session, bool delete_source);
friend void tr_sessionSetEncryption(tr_session* session, tr_encryption_mode mode);
+ friend void tr_sessionSetIdleLimit(tr_session* session, uint16_t idle_minutes);
friend void tr_sessionSetIdleLimited(tr_session* session, bool is_limited);
friend void tr_sessionSetIncompleteFileNamingEnabled(tr_session* session, bool enabled);
friend void tr_sessionSetLPDEnabled(tr_session* session, bool enabled);
@@ -731,12 +734,35 @@ private:
friend void tr_sessionSetQueueStalledMinutes(tr_session* session, int minutes);
friend void tr_sessionSetRPCCallback(tr_session* session, tr_rpc_func func, void* user_data);
friend void tr_sessionSetRatioLimit(tr_session* session, double desired_ratio);
+ friend void tr_sessionSetRatioLimited(tr_session* session, bool is_limited);
+ friend void tr_sessionSetSpeedLimit_Bps(tr_session* session, tr_direction dir, unsigned int Bps);
+ friend void tr_sessionSetUTPEnabled(tr_session* session, bool enabled);
+ std::vector> blocklists_;
+
+ tr_announce_list default_trackers_;
+
+ tr_session_id session_id_;
+
+ std::array speed_limit_Bps_ = { 0U, 0U };
+ std::array speed_limit_enabled_ = { false, false };
+
+ int umask_ = 022;
+
+ // One of 's IPTOS_ values.
+ // See tr_netTos*() in libtransmission/net.h for more info
+ int peer_socket_tos_ = *tr_netTosFromName(TR_DEFAULT_PEER_SOCKET_TOS_STR);
+
+ bool is_utp_enabled_ = false;
bool is_pex_enabled_ = false;
bool is_dht_enabled_ = false;
bool is_lpd_enabled_ = false;
bool is_idle_limited_ = false;
+ bool is_prefetch_enabled_ = false;
+ bool is_ratio_limited_ = false;
+
+ uint8_t peer_id_ttl_hours_ = 6;
struct init_data;
void initImpl(init_data&);
@@ -753,6 +779,8 @@ private:
float desired_ratio_ = 2.0F;
+ uint16_t upload_slots_per_torrent_ = 8;
+
bool should_pause_added_torrents_ = false;
bool should_delete_source_torrents_ = false;
bool should_scrape_paused_torrents_ = false;
@@ -770,6 +798,8 @@ private:
uint16_t peer_limit_ = 200;
uint16_t peer_limit_per_torrent_ = 50;
+ uint16_t idle_limit_minutes_;
+
std::array queue_enabled_ = { false, false };
std::array queue_size_ = { 0, 0 };
int queue_stalled_minutes_ = 0;
@@ -777,9 +807,31 @@ private:
static std::recursive_mutex session_mutex_;
+ class WebMediator final : public tr_web::Mediator
+ {
+ public:
+ explicit WebMediator(tr_session* session)
+ : session_{ session }
+ {
+ }
+ ~WebMediator() override = default;
+
+ [[nodiscard]] std::optional cookieFile() const override;
+ [[nodiscard]] std::optional publicAddress() const override;
+ [[nodiscard]] std::optional userAgent() const override;
+ [[nodiscard]] unsigned int clamp(int torrent_id, unsigned int byte_count) const override;
+ void notifyBandwidthConsumed(int torrent_id, size_t byte_count) override;
+ // runs the tr_web::fetch response callback in the libtransmission thread
+ void run(tr_web::FetchDoneFunc&& func, tr_web::FetchResponse&& response) const override;
+
+ private:
+ tr_session* const session_;
+ };
+
WebMediator web_mediator_{ this };
std::shared_ptr const event_base_;
+ std::shared_ptr const evdns_base_;
std::unique_ptr const timer_maker_;
void onNowTimer();
diff --git a/libtransmission/torrent.cc b/libtransmission/torrent.cc
index 791655c5a..f5dd7f602 100644
--- a/libtransmission/torrent.cc
+++ b/libtransmission/torrent.cc
@@ -167,7 +167,7 @@ static void tr_torrentUnsetPeerId(tr_torrent* tor)
static int peerIdTTL(tr_torrent const* tor)
{
auto const ctime = tor->peer_id_creation_time_;
- return ctime == 0 ? 0 : (int)difftime(ctime + tor->session->peer_id_ttl_hours * 3600, tr_time());
+ return ctime == 0 ? 0 : (int)difftime(ctime + tor->session->peerIdTTLHours() * 3600, tr_time());
}
tr_peer_id_t const& tr_torrentGetPeerId(tr_torrent* tor)
@@ -298,14 +298,14 @@ double tr_torrentGetRatioLimit(tr_torrent const* tor)
bool tr_torrentGetSeedRatio(tr_torrent const* tor, double* ratio)
{
- auto isLimited = bool{};
+ auto is_limited = bool{};
TR_ASSERT(tr_isTorrent(tor));
switch (tr_torrentGetRatioMode(tor))
{
case TR_RATIOLIMIT_SINGLE:
- isLimited = true;
+ is_limited = true;
if (ratio != nullptr)
{
@@ -315,9 +315,9 @@ bool tr_torrentGetSeedRatio(tr_torrent const* tor, double* ratio)
break;
case TR_RATIOLIMIT_GLOBAL:
- isLimited = tr_sessionIsRatioLimited(tor->session);
+ is_limited = tor->session->isRatioLimited();
- if (isLimited && ratio != nullptr)
+ if (is_limited && ratio != nullptr)
{
*ratio = tor->session->desiredRatio();
}
@@ -325,11 +325,11 @@ bool tr_torrentGetSeedRatio(tr_torrent const* tor, double* ratio)
break;
default: /* TR_RATIOLIMIT_UNLIMITED */
- isLimited = false;
+ is_limited = false;
break;
}
- return isLimited;
+ return is_limited;
}
/* returns true if the seed ratio applies --
@@ -432,7 +432,7 @@ bool tr_torrentGetSeedIdle(tr_torrent const* tor, uint16_t* idleMinutes)
if (isLimited && idleMinutes != nullptr)
{
- *idleMinutes = tr_sessionGetIdleLimit(tor->session);
+ *idleMinutes = tor->session->idleLimitMinutes();
}
break;
@@ -770,7 +770,7 @@ static void torrentInit(tr_torrent* tor, tr_ctor const* ctor)
if ((loaded & tr_resume::Idlelimit) == 0)
{
tr_torrentSetIdleMode(tor, TR_IDLELIMIT_GLOBAL);
- tr_torrentSetIdleLimit(tor, tr_sessionGetIdleLimit(tor->session));
+ tr_torrentSetIdleLimit(tor, tor->session->idleLimitMinutes());
}
auto has_local_data = std::optional{};
diff --git a/libtransmission/tr-udp.cc b/libtransmission/tr-udp.cc
index 40fd75805..dc42c8ea7 100644
--- a/libtransmission/tr-udp.cc
+++ b/libtransmission/tr-udp.cc
@@ -92,7 +92,7 @@ static void set_socket_buffers(tr_socket_t fd, bool large)
void tr_udpSetSocketBuffers(tr_session* session)
{
- bool const utp = tr_sessionIsUTPEnabled(session);
+ bool const utp = session->allowsUTP();
if (session->udp_socket != TR_BAD_SOCKET)
{
@@ -260,7 +260,7 @@ static void event_callback(evutil_socket_t s, [[maybe_unused]] short type, void*
}
else
{
- if (tr_sessionIsUTPEnabled(session))
+ if (session->allowsUTP())
{
if (!tr_utpPacket(buf, rc, (struct sockaddr*)&from, fromlen, session))
{
diff --git a/libtransmission/tr-utp.cc b/libtransmission/tr-utp.cc
index 812231ef9..9a5587a57 100644
--- a/libtransmission/tr-utp.cc
+++ b/libtransmission/tr-utp.cc
@@ -83,7 +83,7 @@ static void utp_on_accept(tr_session* const session, UTPSocket* const s)
tr_address addr;
tr_port port;
- if (!tr_sessionIsUTPEnabled(session))
+ if (!session->allowsUTP())
{
utp_close(s);
return;
@@ -161,7 +161,7 @@ static void reset_timer(tr_session* session)
auto interval = std::chrono::milliseconds{};
auto const random_percent = tr_rand_int_weak(1000) / 1000.0;
- if (tr_sessionIsUTPEnabled(session))
+ if (session->allowsUTP())
{
static auto constexpr MinInterval = UtpInterval * 0.5;
static auto constexpr MaxInterval = UtpInterval * 1.5;
diff --git a/libtransmission/transmission.h b/libtransmission/transmission.h
index 68060525f..e5663c7bc 100644
--- a/libtransmission/transmission.h
+++ b/libtransmission/transmission.h
@@ -530,6 +530,7 @@ enum tr_direction
**** Primary session speed limits
***/
+void tr_sessionSetSpeedLimit_Bps(tr_session*, tr_direction, unsigned int Bps);
void tr_sessionSetSpeedLimit_KBps(tr_session*, tr_direction, unsigned int KBps);
unsigned int tr_sessionGetSpeedLimit_KBps(tr_session const*, tr_direction);
@@ -582,7 +583,7 @@ void tr_sessionSetAltSpeedFunc(tr_session*, tr_altSpeedFunc, void*);
double tr_sessionGetRawSpeed_KBps(tr_session const*, tr_direction);
-void tr_sessionSetRatioLimited(tr_session*, bool isLimited);
+void tr_sessionSetRatioLimited(tr_session*, bool is_limited);
bool tr_sessionIsRatioLimited(tr_session const*);
void tr_sessionSetRatioLimit(tr_session*, double desired_ratio);
@@ -591,7 +592,7 @@ double tr_sessionGetRatioLimit(tr_session const*);
void tr_sessionSetIdleLimited(tr_session*, bool is_limited);
bool tr_sessionIsIdleLimited(tr_session const*);
-void tr_sessionSetIdleLimit(tr_session*, uint16_t idleMinutes);
+void tr_sessionSetIdleLimit(tr_session*, uint16_t idle_minutes);
uint16_t tr_sessionGetIdleLimit(tr_session const*);
void tr_sessionSetPeerLimit(tr_session*, uint16_t max_global_peers);
@@ -754,7 +755,7 @@ bool tr_sessionIsScriptEnabled(tr_session const*, TrScript);
*
* Passing nullptr for a filename will clear the blocklist.
*/
-size_t tr_blocklistSetContent(tr_session* session, char const* filename);
+size_t tr_blocklistSetContent(tr_session* session, char const* content_filename);
size_t tr_blocklistGetRuleCount(tr_session const* session);
diff --git a/libtransmission/trevent.cc b/libtransmission/trevent.cc
index 3dc166bac..c4db11613 100644
--- a/libtransmission/trevent.cc
+++ b/libtransmission/trevent.cc
@@ -16,7 +16,6 @@
#include
#endif
-#include
#include
#include
@@ -188,11 +187,9 @@ static void libeventThreadFunc(tr_event_handle* events)
// create the libevent base
auto* base = events->session->eventBase();
- auto* const dns_base = evdns_base_new(base, EVDNS_BASE_INITIALIZE_NAMESERVERS);
// initialize the session struct's event fields
events->work_queue_event = event_new(base, -1, 0, onWorkAvailable, events->session);
- events->session->evdns_base = dns_base;
events->session->events = events;
// tell the thread that's waiting in tr_eventInit()
@@ -203,12 +200,7 @@ static void libeventThreadFunc(tr_event_handle* events)
event_base_loop(base, EVLOOP_NO_EXIT_ON_EMPTY);
// shut down the thread
- if (dns_base != nullptr)
- {
- evdns_base_free(dns_base, 0);
- }
event_free(events->work_queue_event);
- events->session->evdns_base = nullptr;
events->session->events = nullptr;
delete events;
tr_logAddTrace("Closing libevent thread");