mirror of
https://github.com/rakshasa/rtorrent.git
synced 2026-08-05 17:52:29 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d8664e6b4c | |||
| 7e907616a2 | |||
| dcf13ab21a | |||
| 03c4467a33 | |||
| fc5ce92c46 | |||
| f1b22023a0 | |||
| 928f3e58a8 | |||
| 743363b405 |
+9
-15
@@ -214,21 +214,15 @@ Add a preferred filename encoding to the list. The encodings are
|
||||
attempted in the order they are inserted, if none match the torrent
|
||||
default is used.
|
||||
.TP
|
||||
\fBencryption = \fIoption\fB,\fI\&...\fB\fR
|
||||
Set how rtorrent should deal with encrypted Bittorrent connections. By
|
||||
default, encryption is disabled, equivalent to specifying the option
|
||||
\fBnone\fR\&. Alternatively, any number of the following
|
||||
options may be specified:
|
||||
|
||||
\fBallow_incoming\fR (allow incoming encrypted connections),
|
||||
\fBtry_outgoing\fR (use encryption for outgoing connections),
|
||||
\fBrequire\fR (disable unencrypted handshakes),
|
||||
\fBrequire_RC4\fR (also disable plaintext transmission after the
|
||||
initial encrypted handshake),
|
||||
\fBenable_retry\fR (if the initial outgoing connection fails, retry
|
||||
with encryption turned on if it was off or off if it was on),
|
||||
\fBprefer_plaintext\fR (choose plaintext when peer offers a choice
|
||||
between plaintext transmission and RC4 encryption, otherwise RC4 will be used).
|
||||
\fBprotocol.encryption.handshake.set\fR (deny, allow, prefer, require)
|
||||
and \fBprotocol.encryption.stream.set\fR (deny, allow, prefer,
|
||||
require) control how rtorrent deals with encrypted Bittorrent
|
||||
connections. Handshake \fBallow\fR accepts plain or PE inbound and
|
||||
tries plain first outbound with one PE retry on failure.
|
||||
\fBprefer\fR tries PE first with one plain retry. Stream \fBallow\fR
|
||||
and \fBprefer\fR offer both handshake-only and RC4 on outgoing PE
|
||||
connections. The default is handshake=allow, stream=allow. Use
|
||||
\fBprotocol.encryption\fR to inspect the effective policy.
|
||||
.TP
|
||||
\fBpeer_exchange = \fIyes | no\fB\fR
|
||||
Enable/disable peer exchange for torrents that aren't marked private. Disabled by default.
|
||||
|
||||
+11
-17
@@ -484,25 +484,19 @@ default is used.
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>encryption = <replaceable>option</replaceable>,<replaceable>...</replaceable></term>
|
||||
<term>protocol.encryption.handshake.set = <replaceable>policy</replaceable></term>
|
||||
<listitem><para>
|
||||
|
||||
Set how rtorrent should deal with encrypted Bittorrent connections. By
|
||||
default, encryption is disabled, equivalent to specifying the option
|
||||
<emphasis>none</emphasis>. Alternatively, any number of the following
|
||||
options may be specified:
|
||||
|
||||
</para><para>
|
||||
|
||||
<emphasis>allow_incoming</emphasis> (allow incoming encrypted connections),
|
||||
<emphasis>try_outgoing</emphasis> (use encryption for outgoing connections),
|
||||
<emphasis>require</emphasis> (disable unencrypted handshakes),
|
||||
<emphasis>require_RC4</emphasis> (also disable plaintext transmission after the
|
||||
initial encrypted handshake),
|
||||
<emphasis>enable_retry</emphasis> (if the initial outgoing connection fails, retry
|
||||
with encryption turned on if it was off or off if it was on),
|
||||
<emphasis>prefer_plaintext</emphasis> (choose plaintext when peer offers a choice
|
||||
between plaintext transmission and RC4 encryption, otherwise RC4 will be used).
|
||||
Control how rtorrent deals with encrypted Bittorrent connections.
|
||||
<emphasis>protocol.encryption.handshake.set</emphasis> (deny, allow, prefer,
|
||||
require) and <emphasis>protocol.encryption.stream.set</emphasis> (deny, allow,
|
||||
prefer, require). Handshake <emphasis>allow</emphasis> accepts plain or PE
|
||||
inbound and tries plain first outbound with one PE retry on failure.
|
||||
<emphasis>prefer</emphasis> tries PE first with one plain retry. Stream
|
||||
<emphasis>allow</emphasis> and <emphasis>prefer</emphasis> offer both
|
||||
handshake-only and RC4 on outgoing PE connections. The default is
|
||||
handshake=allow, stream=allow. Use <emphasis>protocol.encryption</emphasis> to
|
||||
inspect the effective policy.
|
||||
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
+32
-6
@@ -95,14 +95,40 @@
|
||||
#schedule2 = ip_tick,0,1800,ip=rakshasa
|
||||
#schedule2 = bind_tick,0,1800,bind=rakshasa
|
||||
|
||||
# Encryption options, set to none (default) or any combination of the following:
|
||||
# allow_incoming, try_outgoing, require, require_RC4, enable_retry, prefer_plaintext
|
||||
# --- Protocol encryption (PE handshake / optional RC4 stream) ---
|
||||
# Default at startup: handshake=allow stream=allow
|
||||
#
|
||||
# The example value allows incoming encrypted connections, starts unencrypted
|
||||
# outgoing connections but retries with encryption if they fail, preferring
|
||||
# plain-text to RC4 encryption after the encrypted handshake.
|
||||
# Handshake (PE handshake; incoming accepts plain or PE for allow/prefer):
|
||||
# deny - plain BT handshake only both ways; no retry
|
||||
# allow - accept plain or PE inbound; plain first outbound with one PE retry
|
||||
# prefer - accept plain or PE inbound; PE first outbound with one plain retry
|
||||
# require - PE handshake required both ways; no retry
|
||||
#
|
||||
# protocol.encryption.set = allow_incoming,enable_retry,prefer_plaintext
|
||||
# protocol.encryption.handshake.set = allow
|
||||
#
|
||||
# Stream (cipher negotiation after PE handshake succeeds):
|
||||
# deny - offer handshake-only; require handshake-only (no RC4)
|
||||
# allow - incoming: prefer handshake-only if offered, else RC4
|
||||
# outgoing: offer both handshake-only and RC4
|
||||
# prefer - incoming: pick RC4 if offered, else handshake-only
|
||||
# outgoing: offer both handshake-only and RC4
|
||||
# require - offer RC4 only; require RC4
|
||||
#
|
||||
# Outgoing retry summary with handshake=allow (plain first):
|
||||
# stream=allow/prefer -> plain BT -> PE (both)
|
||||
# stream=deny -> plain BT -> PE (handshake-only)
|
||||
# stream=require -> plain BT -> PE (RC4-only)
|
||||
#
|
||||
# Outgoing retry summary with handshake=prefer (PE first):
|
||||
# stream=allow/prefer -> PE (both) -> plain BT
|
||||
# stream=deny -> PE (handshake-only) -> plain BT
|
||||
# stream=require -> PE (RC4-only) -> plain BT
|
||||
#
|
||||
# Negotiated stream cipher is logged at connection_handshake level.
|
||||
#
|
||||
# protocol.encryption.stream.set = allow
|
||||
#
|
||||
# Use protocol.encryption to inspect the effective policy.
|
||||
|
||||
# Enable DHT support for trackerless torrents or when all trackers are down.
|
||||
# May be set to "disable" (completely disable DHT), "off" (do not start DHT),
|
||||
|
||||
@@ -42,7 +42,8 @@ throttle.min_peers.seed.set = 30
|
||||
throttle.max_peers.seed.set = 80
|
||||
trackers.numwant.set = 80
|
||||
|
||||
protocol.encryption.set = allow_incoming,try_outgoing,enable_retry
|
||||
protocol.encryption.handshake.set = allow
|
||||
protocol.encryption.stream.set = prefer
|
||||
|
||||
# Limits for file handle resources, this is optimized for
|
||||
# an `ulimit` of 1024 (a common default). You MUST leave
|
||||
|
||||
@@ -72,7 +72,8 @@ rc.throttle.min_peers.seed = 30
|
||||
rc.throttle.max_peers.seed = 80
|
||||
rc.trackers.numwant = 80
|
||||
|
||||
rc.protocol.encryption.set('allow_incoming', 'try_outgoing', 'enable_retry')
|
||||
rc.protocol.encryption.handshake.set('allow')
|
||||
rc.protocol.encryption.stream.set('prefer')
|
||||
|
||||
-- Limits for file handle resources, this is optimized for
|
||||
-- an `ulimit` of 1024 (a common default). You MUST leave
|
||||
|
||||
@@ -12,7 +12,7 @@ echo "Client version: " `xmlrpc2scgi.py -p scgi://127.0.0.1:${PORT_NUMBER} syste
|
||||
echo
|
||||
echo "Generated by 'rtorrent/doc/scripts/print_option_string.sh' on `date -u`."
|
||||
|
||||
for i in strings.choke_heuristics strings.choke_heuristics.upload strings.choke_heuristics.download strings.connection_type strings.encryption strings.ip_filter strings.ip_tos strings.log_group strings.tracker_event strings.tracker_mode; do
|
||||
for i in strings.choke_heuristics strings.choke_heuristics.upload strings.choke_heuristics.download strings.connection_type strings.encryption.handshake strings.encryption.stream strings.ip_filter strings.ip_tos strings.log_group strings.tracker_event strings.tracker_mode; do
|
||||
echo
|
||||
echo $i
|
||||
echo `echo $i | tr 'a-z_.' '-'`
|
||||
|
||||
@@ -188,6 +188,8 @@ libsub_root_a_SOURCES = \
|
||||
command_local.cc \
|
||||
command_logging.cc \
|
||||
command_network.cc \
|
||||
encryption_config.cc \
|
||||
encryption_config.h \
|
||||
command_peer.cc \
|
||||
command_throttle.cc \
|
||||
command_tracker.cc \
|
||||
|
||||
@@ -448,7 +448,8 @@ initialize_command_dynamic() {
|
||||
CMD2_ANY ("strings.choke_heuristics.upload", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_UPLOAD));
|
||||
CMD2_ANY ("strings.choke_heuristics.download", std::bind(&torrent::option_list_strings, torrent::OPTION_CHOKE_HEURISTICS_DOWNLOAD));
|
||||
CMD2_ANY ("strings.connection_type", std::bind(&torrent::option_list_strings, torrent::OPTION_CONNECTION_TYPE));
|
||||
CMD2_ANY ("strings.encryption", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION));
|
||||
CMD2_ANY ("strings.encryption.handshake", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION_MODE));
|
||||
CMD2_ANY ("strings.encryption.stream", std::bind(&torrent::option_list_strings, torrent::OPTION_ENCRYPTION_MODE));
|
||||
CMD2_ANY ("strings.ip_filter", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_FILTER));
|
||||
CMD2_ANY ("strings.ip_tos", std::bind(&torrent::option_list_strings, torrent::OPTION_IP_TOS));
|
||||
CMD2_ANY ("strings.log_group", std::bind(&torrent::option_list_strings, torrent::OPTION_LOG_GROUP));
|
||||
@@ -472,7 +473,8 @@ initialize_command_dynamic() {
|
||||
rpc::rpc.mark_safe("strings.choke_heuristics.upload");
|
||||
rpc::rpc.mark_safe("strings.choke_heuristics.download");
|
||||
rpc::rpc.mark_safe("strings.connection_type");
|
||||
rpc::rpc.mark_safe("strings.encryption");
|
||||
rpc::rpc.mark_safe("strings.encryption.handshake");
|
||||
rpc::rpc.mark_safe("strings.encryption.stream");
|
||||
rpc::rpc.mark_safe("strings.ip_filter");
|
||||
rpc::rpc.mark_safe("strings.ip_tos");
|
||||
rpc::rpc.mark_safe("strings.log_group");
|
||||
|
||||
+25
-24
@@ -8,10 +8,10 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/chunk_manager.h>
|
||||
#include <torrent/data/file_manager.h>
|
||||
#include <torrent/data/chunk_utils.h>
|
||||
#include <torrent/runtime/runtime.h>
|
||||
#include <torrent/runtime/memory_manager.h>
|
||||
#include <torrent/runtime/socket_manager.h>
|
||||
#include <torrent/utils/chrono.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
@@ -188,7 +188,6 @@ cmd_file_append(const torrent::Object::list_type& args) {
|
||||
void
|
||||
initialize_command_local() {
|
||||
core::DownloadList* dList = control->core()->download_list();
|
||||
torrent::ChunkManager* chunkManager = torrent::chunk_manager();
|
||||
torrent::FileManager* fileManager = torrent::file_manager();
|
||||
|
||||
if (rpc::call_command_value("method.use_deprecated") == 1) {
|
||||
@@ -265,32 +264,34 @@ initialize_command_local() {
|
||||
CMD_ANY_VALUE_V(category_name + ".max_alloc.set", [category](auto, auto& value) { torrent::runtime::socket_manager()->set_category_max_allocation(category, value); });
|
||||
}
|
||||
|
||||
CMD_ANY ("pieces.sync.always_safe", std::bind(&CM_t::safe_sync, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.sync.always_safe.set", std::bind(&CM_t::set_safe_sync, chunkManager, std::placeholders::_2));
|
||||
CMD_ANY ("pieces.sync.safe_free_diskspace", std::bind(&CM_t::safe_free_diskspace, chunkManager));
|
||||
CMD_ANY ("pieces.sync.timeout", std::bind(&CM_t::timeout_sync, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.sync.timeout.set", std::bind(&CM_t::set_timeout_sync, chunkManager, std::placeholders::_2));
|
||||
CMD_ANY ("pieces.sync.timeout_safe", std::bind(&CM_t::timeout_safe_sync, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", std::bind(&CM_t::set_timeout_safe_sync, chunkManager, std::placeholders::_2));
|
||||
CMD_ANY ("pieces.sync.queue_size", std::bind(&CM_t::sync_queue_size, chunkManager));
|
||||
CMD_ANY ("pieces.sync.always_safe", [](auto, auto) { return torrent::runtime::memory_manager()->safe_sync(); });
|
||||
CMD_ANY_VALUE_V ("pieces.sync.always_safe.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_safe_sync(value); });
|
||||
CMD_ANY ("pieces.sync.safe_free_diskspace", [](auto, auto) { return torrent::runtime::memory_manager()->sync_safe_free_diskspace(); });
|
||||
CMD_ANY ("pieces.sync.timeout", [](auto, auto) { return torrent::runtime::memory_manager()->timeout_sync().count(); });
|
||||
CMD_ANY_VALUE_V ("pieces.sync.timeout.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_timeout_sync(value); });
|
||||
// CMD_ANY ("pieces.sync.timeout_safe", [](auto, auto) { return torrent::runtime::memory_manager()->timeout_safe_sync(); });
|
||||
// CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_timeout_safe_sync(value); });
|
||||
CMD_ANY ("pieces.sync.timeout_safe", [](auto, auto) { return 0; });
|
||||
CMD_ANY_VALUE_V ("pieces.sync.timeout_safe.set", [](auto, auto) { });
|
||||
CMD_ANY ("pieces.sync.queue_size", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_block_count(); });
|
||||
|
||||
CMD_ANY ("pieces.preload.type", std::bind(&CM_t::preload_type, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.preload.type.set", std::bind(&CM_t::set_preload_type, chunkManager, std::placeholders::_2));
|
||||
CMD_ANY ("pieces.preload.min_size", std::bind(&CM_t::preload_min_size, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.preload.min_size.set", std::bind(&CM_t::set_preload_min_size, chunkManager, std::placeholders::_2));
|
||||
CMD_ANY ("pieces.preload.min_rate", std::bind(&CM_t::preload_required_rate, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.preload.min_rate.set", std::bind(&CM_t::set_preload_required_rate, chunkManager, std::placeholders::_2));
|
||||
|
||||
CMD_ANY ("pieces.memory.current", std::bind(&CM_t::memory_usage, chunkManager));
|
||||
CMD_ANY ("pieces.memory.sync_queue", std::bind(&CM_t::sync_queue_memory_usage, chunkManager));
|
||||
CMD_ANY ("pieces.memory.block_count", std::bind(&CM_t::memory_block_count, chunkManager));
|
||||
CMD_ANY ("pieces.memory.max", std::bind(&CM_t::max_memory_usage, chunkManager));
|
||||
CMD_ANY_VALUE_V ("pieces.memory.max.set", std::bind(&CM_t::set_max_memory_usage, chunkManager, std::placeholders::_2));
|
||||
CMD_ANY ("pieces.stats_preloaded", std::bind(&CM_t::stats_preloaded, chunkManager));
|
||||
CMD_ANY ("pieces.stats_not_preloaded", std::bind(&CM_t::stats_not_preloaded, chunkManager));
|
||||
CMD_ANY ("pieces.preload.type", [](auto, auto) { return torrent::runtime::memory_manager()->preload_type(); });
|
||||
CMD_ANY_VALUE_V ("pieces.preload.type.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_type(value); });
|
||||
CMD_ANY ("pieces.preload.min_size", [](auto, auto) { return torrent::runtime::memory_manager()->preload_min_size(); });
|
||||
CMD_ANY_VALUE_V ("pieces.preload.min_size.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_min_size(value); });
|
||||
CMD_ANY ("pieces.preload.min_rate", [](auto, auto) { return torrent::runtime::memory_manager()->preload_required_rate(); });
|
||||
CMD_ANY_VALUE_V ("pieces.preload.min_rate.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_preload_required_rate(value); });
|
||||
|
||||
CMD_ANY ("pieces.stats_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_preloaded(); });
|
||||
CMD_ANY ("pieces.stats_not_preloaded", [](auto, auto) { return torrent::runtime::memory_manager()->stats_not_preloaded(); });
|
||||
CMD_ANY ("pieces.stats.total_size", std::bind(&apply_pieces_stats_total_size));
|
||||
|
||||
CMD_ANY ("pieces.memory.current", [](auto, auto) { return torrent::runtime::memory_manager()->memory_usage(); });
|
||||
CMD_ANY ("pieces.memory.sync_queue", [](auto, auto) { return torrent::runtime::memory_manager()->sync_queue_memory_usage(); });
|
||||
CMD_ANY ("pieces.memory.block_count", [](auto, auto) { return torrent::runtime::memory_manager()->memory_block_count(); });
|
||||
CMD_ANY ("pieces.memory.max", [](auto, auto) { return torrent::runtime::memory_manager()->max_memory_usage(); });
|
||||
CMD_ANY_VALUE_V ("pieces.memory.max.set", [](auto, auto& value) { return torrent::runtime::memory_manager()->set_max_memory_usage(value); });
|
||||
|
||||
CMD_ANY ("pieces.hash.queue_size", std::bind(&torrent::main_thread::hash_queue_size));
|
||||
CMD_VAR_BOOL ("pieces.hash.on_completion", true);
|
||||
|
||||
|
||||
+13
-27
@@ -9,7 +9,9 @@
|
||||
#include <torrent/download/resource_manager.h>
|
||||
#include <torrent/net/http_stack.h>
|
||||
#include <torrent/net/socket_address.h>
|
||||
#include <torrent/runtime/client_config.h>
|
||||
#include <torrent/runtime/network_config.h>
|
||||
#include <torrent/runtime/network_manager.h>
|
||||
#include <torrent/runtime/proxy_manager.h>
|
||||
#include <torrent/runtime/runtime.h>
|
||||
#include <torrent/runtime/socket_manager.h>
|
||||
@@ -17,6 +19,7 @@
|
||||
#include <torrent/utils/log.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
#include "encryption_config.h"
|
||||
#include "globals.h"
|
||||
#include "control.h"
|
||||
#include "command_helpers.h"
|
||||
@@ -32,24 +35,6 @@
|
||||
#include <systemd/sd-daemon.h>
|
||||
#endif
|
||||
|
||||
torrent::Object
|
||||
apply_encryption(const torrent::Object::list_type& args) {
|
||||
uint32_t options_mask = torrent::runtime::NetworkConfig::encryption_none;
|
||||
|
||||
for (const auto& arg : args) {
|
||||
uint32_t opt = torrent::option_find_string(torrent::OPTION_ENCRYPTION, arg.as_string().c_str());
|
||||
|
||||
if (opt == torrent::runtime::NetworkConfig::encryption_none)
|
||||
options_mask = torrent::runtime::NetworkConfig::encryption_none;
|
||||
else
|
||||
options_mask |= opt;
|
||||
}
|
||||
|
||||
torrent::runtime::network_config()->set_encryption_options(options_mask);
|
||||
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_tos(const torrent::Object::string_type& arg) {
|
||||
rpc::command_base::value_type value;
|
||||
@@ -220,17 +205,18 @@ initialize_command_network() {
|
||||
auto http_stack = torrent::net_thread::http_stack();
|
||||
auto nw_config = torrent::runtime::network_config();
|
||||
|
||||
// Isn't port_open used?
|
||||
CMD_VAR_BOOL ("network.port_open", true);
|
||||
CMD_VAR_BOOL ("network.port_random", true);
|
||||
CMD_VAR_STRING ("network.port_range", "6881-6999");
|
||||
|
||||
CMD_ANY ("network.listen.port", [](auto, auto) { return torrent::runtime::listen_port(); });
|
||||
CMD_ANY ("network.listen.backlog", [nw_config](auto, auto) { return nw_config->listen_backlog(); });
|
||||
CMD_ANY_VALUE_V ("network.listen.backlog.set", [nw_config](auto, auto& value) { return nw_config->set_listen_backlog(value); });
|
||||
CMD_ANY ("network.listen.port", [](auto, auto) { return torrent::runtime::network_manager()->listen_port(); });
|
||||
CMD_ANY_VALUE_V ("network.listen.port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_listen_port(value); });
|
||||
CMD_ANY ("network.listen.port.random", [](auto, auto) { return torrent::runtime::client_config()->listen_port_random(); });
|
||||
CMD_ANY_VALUE_V ("network.listen.port.random.set", [](auto, auto& value) { return torrent::runtime::client_config()->set_listen_port_random(value); });
|
||||
CMD_ANY ("network.listen.port.range", [](auto, auto) { return listen_port_range(); });
|
||||
CMD_ANY_STRING_V("network.listen.port.range.set", [](auto, auto& value) { return set_listen_port_range(value); });
|
||||
CMD_ANY ("network.listen.backlog", [](auto, auto) { return torrent::runtime::network_config()->listen_backlog(); });
|
||||
CMD_ANY_VALUE_V ("network.listen.backlog.set", [](auto, auto& value) { return torrent::runtime::network_config()->set_listen_backlog(value); });
|
||||
|
||||
CMD_VAR_BOOL ("protocol.pex", true);
|
||||
CMD_ANY_LIST ("protocol.encryption.set", [](auto, auto& args) { return apply_encryption(args); });
|
||||
|
||||
encryption_config::initialize_commands();
|
||||
|
||||
CMD_VAR_STRING ("protocol.connection.leech", "leech");
|
||||
CMD_VAR_STRING ("protocol.connection.seed", "seed");
|
||||
|
||||
@@ -142,7 +142,7 @@ initialize_command_tracker() {
|
||||
lt_log_print(torrent::LOG_DHT_ERROR, "dht.port.set is no longer supported, use dht.override_port.set", 0);
|
||||
});
|
||||
CMD2_ANY ("dht.override_port", [](auto, auto) { return torrent::runtime::network_config()->override_dht_port(); });
|
||||
CMD2_ANY_VALUE_V ("dht.override_port.set", [](auto, auto& value) { return torrent::runtime::network_config()->set_override_dht_port(value); });
|
||||
CMD2_ANY_VALUE_V ("dht.override_port.set", [](auto, auto& value) { return torrent::runtime::network_manager()->set_dht_port(value); });
|
||||
|
||||
CMD2_ANY_STRING ("dht.add_node", [](auto, auto& str) { return apply_dht_add_node(str); });
|
||||
CMD2_ANY ("dht.statistics", [](auto, auto) { return control->dht_manager()->dht_statistics(); });
|
||||
|
||||
@@ -70,9 +70,6 @@ Control::initialize() {
|
||||
display::Window::slot_unschedule([this](display::Window* w) { m_display->unschedule(w); });
|
||||
display::Window::slot_adjust([this]() { m_display->adjust_layout(); });
|
||||
|
||||
torrent::net_thread::http_stack()->set_user_agent(USER_AGENT);
|
||||
|
||||
m_core->listen_open();
|
||||
m_core->set_hashing_view(*m_view_manager->find_throw("hashing"));
|
||||
|
||||
m_ui->init(this);
|
||||
|
||||
+21
-7
@@ -8,6 +8,7 @@
|
||||
#include <torrent/object_stream.h>
|
||||
#include <torrent/rate.h>
|
||||
#include <torrent/runtime/network_manager.h>
|
||||
#include <torrent/runtime/runtime.h>
|
||||
#include <torrent/tracker/dht_controller.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
@@ -141,18 +142,29 @@ DhtManager::save_dht_cache() {
|
||||
|
||||
void
|
||||
DhtManager::set_mode_by_user(const std::string& arg) {
|
||||
for (int i = 0; i < dht_settings_num; i++) {
|
||||
if (arg == dht_settings[i]) {
|
||||
m_set_by_user = true;
|
||||
return set_mode_directly(i);
|
||||
}
|
||||
unsigned int mode = [arg]() {
|
||||
for (int i = 0; i < dht_settings_num; i++) {
|
||||
if (arg == dht_settings[i])
|
||||
return i;
|
||||
}
|
||||
|
||||
throw torrent::input_error("Invalid dht mode: " + arg);
|
||||
}();
|
||||
|
||||
m_set_by_user = true;
|
||||
|
||||
if (!torrent::runtime::is_network_initialized()) {
|
||||
m_start = mode;
|
||||
return;
|
||||
}
|
||||
|
||||
set_mode_directly(mode);
|
||||
}
|
||||
|
||||
void
|
||||
DhtManager::set_mode_directly(unsigned int mode) {
|
||||
if (mode >= dht_settings_num)
|
||||
throw torrent::input_error("Invalid argument.");
|
||||
throw torrent::input_error("Invalid dht mode.");
|
||||
|
||||
m_start = mode;
|
||||
|
||||
@@ -164,8 +176,10 @@ DhtManager::set_mode_directly(unsigned int mode) {
|
||||
|
||||
void
|
||||
DhtManager::set_auto_if_untouched_and_has_session() {
|
||||
if (m_set_by_user)
|
||||
if (m_set_by_user) {
|
||||
set_mode_directly(m_start);
|
||||
return;
|
||||
}
|
||||
|
||||
if (rpc::call_command_string("session.path").empty()) {
|
||||
LT_LOG("DHT auto-start disabled, session path not set.", 0);
|
||||
|
||||
@@ -104,40 +104,42 @@ DownloadFactory::receive_load() {
|
||||
throw torrent::internal_error("DownloadFactory::load*() called on an object with m_stream != NULL");
|
||||
|
||||
if (is_network_uri(m_uri)) {
|
||||
// Http handling here.
|
||||
m_stream.reset(new std::stringstream);
|
||||
|
||||
m_manager->http_queue()->insert(m_uri, m_stream,
|
||||
[this]() { receive_loaded(); },
|
||||
[this](const std::string& error) { receive_failed(error); }
|
||||
);
|
||||
auto done_fn = [this]() { receive_loaded(); };
|
||||
auto failed_fn = [this](const std::string& error) { receive_failed(error); };
|
||||
|
||||
m_manager->http_queue()->insert(m_uri, m_stream, done_fn, failed_fn);
|
||||
|
||||
m_variables["tied_to_file"] = (int64_t)false;
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (is_magnet_uri(m_uri)) {
|
||||
if (is_magnet_uri(m_uri)) {
|
||||
// DEBUG: Use m_object.
|
||||
m_stream.reset(new std::stringstream());
|
||||
*m_stream << "d10:magnet-uri" << m_uri.length() << ":" << m_uri << "e";
|
||||
|
||||
m_variables["tied_to_file"] = (int64_t)false;
|
||||
receive_loaded();
|
||||
|
||||
} else {
|
||||
std::fstream stream(expand_path(m_uri).c_str(), std::ios::in | std::ios::binary);
|
||||
|
||||
if (!stream.is_open())
|
||||
return receive_failed("Could not open file");
|
||||
|
||||
m_object = new torrent::Object;
|
||||
stream >> *m_object;
|
||||
|
||||
if (!stream.good())
|
||||
return receive_failed("Reading torrent file failed");
|
||||
|
||||
m_isFile = true;
|
||||
|
||||
receive_loaded();
|
||||
return;
|
||||
}
|
||||
|
||||
std::fstream stream(expand_path(m_uri).c_str(), std::ios::in | std::ios::binary);
|
||||
|
||||
if (!stream.is_open())
|
||||
return receive_failed("Could not open file");
|
||||
|
||||
m_object = new torrent::Object;
|
||||
stream >> *m_object;
|
||||
|
||||
if (!stream.good())
|
||||
return receive_failed("Reading torrent file failed");
|
||||
|
||||
m_isFile = true;
|
||||
|
||||
receive_loaded();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -19,14 +19,11 @@ HttpQueue::insert(const std::string& url, std::shared_ptr<std::ostream> stream,
|
||||
for (auto& slot : m_signal_insert)
|
||||
slot(*itr);
|
||||
|
||||
itr->add_done_slot(torrent::this_thread::thread(), [this, itr]() { erase(itr); });
|
||||
itr->add_failed_slot(torrent::this_thread::thread(), [this, itr](auto) { erase(itr); });
|
||||
|
||||
itr->add_done_slot(torrent::this_thread::thread(), std::move(done_fn));
|
||||
itr->add_failed_slot(torrent::this_thread::thread(), std::move(failed_fn));
|
||||
itr->add_done_slot(torrent::this_thread::thread(), [this, itr]() { erase(itr); });
|
||||
|
||||
// TODO: Downloading http torrents doesn't seem to work.
|
||||
// TODO: Quitting no longer works.
|
||||
itr->add_failed_slot(torrent::this_thread::thread(), std::move(failed_fn));
|
||||
itr->add_failed_slot(torrent::this_thread::thread(), [this, itr](auto) { erase(itr); });
|
||||
|
||||
torrent::net_thread::http_stack()->start_get(*itr);
|
||||
|
||||
|
||||
+2
-34
@@ -33,6 +33,8 @@
|
||||
#include "core/http_queue.h"
|
||||
#include "core/view.h"
|
||||
|
||||
#include <torrent/runtime/client_config.h>
|
||||
|
||||
namespace core {
|
||||
|
||||
const int Manager::create_start;
|
||||
@@ -160,40 +162,6 @@ Manager::shutdown(bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Manager::listen_open() {
|
||||
// This stuff really should be moved outside of manager, make it
|
||||
// part of the init script.
|
||||
if (!rpc::call_command_value("network.port_open"))
|
||||
return;
|
||||
|
||||
int portFirst, portLast;
|
||||
torrent::Object portRange = rpc::call_command("network.port_range");
|
||||
|
||||
if (!portRange.is_string())
|
||||
throw torrent::input_error("Invalid port_range argument type.");
|
||||
|
||||
if (std::sscanf(portRange.as_string().c_str(), "%i-%i", &portFirst, &portLast) != 2)
|
||||
throw torrent::input_error("Invalid port_range argument.");
|
||||
|
||||
if (portFirst > portLast || portLast >= (1 << 16))
|
||||
throw torrent::input_error("Invalid port range.");
|
||||
|
||||
if (rpc::call_command_value("network.port_random")) {
|
||||
int boundary = portFirst + random() % (portLast - portFirst + 1);
|
||||
|
||||
if (torrent::runtime::network_manager()->listen_open(boundary, portLast) ||
|
||||
torrent::runtime::network_manager()->listen_open(portFirst, boundary))
|
||||
return;
|
||||
|
||||
} else {
|
||||
if (torrent::runtime::network_manager()->listen_open(portFirst, portLast))
|
||||
return;
|
||||
}
|
||||
|
||||
throw torrent::input_error("Could not open/bind port for listening: " + std::string(std::strerror(errno)));
|
||||
}
|
||||
|
||||
void
|
||||
Manager::receive_http_failed(std::string msg) {
|
||||
push_log_std("Http download error: \"" + msg + "\"");
|
||||
|
||||
@@ -55,8 +55,6 @@ public:
|
||||
|
||||
void cleanup();
|
||||
|
||||
void listen_open();
|
||||
|
||||
const std::string& magnet_path();
|
||||
void set_magnet_path(const std::string& path);
|
||||
|
||||
|
||||
@@ -16,6 +16,21 @@
|
||||
|
||||
namespace display {
|
||||
|
||||
namespace {
|
||||
|
||||
char
|
||||
connection_type_char(const torrent::Peer* p) {
|
||||
if (p->is_encrypted())
|
||||
return p->is_incoming() ? 'R' : 'L';
|
||||
|
||||
if (p->is_obfuscated())
|
||||
return p->is_incoming() ? 'H' : 'h';
|
||||
|
||||
return p->is_incoming() ? 'r' : 'l';
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WindowPeerList::WindowPeerList(core::Download* d, PList* l, PList::iterator* f) :
|
||||
Window(new Canvas, 0, 0, 0, extent_full, extent_full),
|
||||
m_download(d),
|
||||
@@ -35,6 +50,7 @@ WindowPeerList::redraw() {
|
||||
m_canvas->print(x, y, "UP"); x += 7;
|
||||
m_canvas->print(x, y, "DOWN"); x += 7;
|
||||
m_canvas->print(x, y, "PEER"); x += 7;
|
||||
// CT: R/H/r or L/h/l (RC4 / handshake-only / plain) + peer type (u/p/ )
|
||||
m_canvas->print(x, y, "CT/RE/LO"); x += 10;
|
||||
m_canvas->print(x, y, "QS"); x += 6;
|
||||
m_canvas->print(x, y, "DONE"); x += 6;
|
||||
@@ -95,7 +111,7 @@ WindowPeerList::redraw() {
|
||||
peerType = ' ';
|
||||
|
||||
m_canvas->print(x, y, "%c%c/%c%c/%c%c",
|
||||
p->is_encrypted() ? (p->is_incoming() ? 'R' : 'L') : (p->is_incoming() ? 'r' : 'l'),
|
||||
connection_type_char(p),
|
||||
peerType,
|
||||
p->is_down_choked() ? std::tolower(remoteChoked) : remoteChoked,
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "encryption_config.h"
|
||||
|
||||
#include <torrent/runtime/network_config.h>
|
||||
#include <torrent/runtime/runtime.h>
|
||||
#include <torrent/utils/option_strings.h>
|
||||
|
||||
#include "command_helpers.h"
|
||||
#include "globals.h"
|
||||
|
||||
namespace encryption_config {
|
||||
namespace {
|
||||
|
||||
Policy
|
||||
current_policy() {
|
||||
return torrent::runtime::network_config()->encryption_policy();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Policy
|
||||
default_policy() {
|
||||
Policy policy;
|
||||
policy.handshake = Policy::Mode::allow;
|
||||
policy.stream = Policy::Mode::allow;
|
||||
return policy;
|
||||
}
|
||||
|
||||
std::string
|
||||
mode_to_string(Policy::Mode value) {
|
||||
return torrent::option_to_str_or_throw(torrent::OPTION_ENCRYPTION_MODE,
|
||||
static_cast<unsigned int>(value));
|
||||
}
|
||||
|
||||
void
|
||||
apply_mode_value(Policy& policy, Policy::Mode Policy::*field, const std::string& value) {
|
||||
policy.*field = static_cast<Policy::Mode>(
|
||||
torrent::option_find_string_str(torrent::OPTION_ENCRYPTION_MODE, value));
|
||||
}
|
||||
|
||||
std::string
|
||||
summary_string(const Policy& policy) {
|
||||
return "handshake=" + mode_to_string(policy.handshake)
|
||||
+ " stream=" + mode_to_string(policy.stream);
|
||||
}
|
||||
|
||||
void
|
||||
apply_policy(const Policy& policy) {
|
||||
torrent::runtime::network_config()->set_encryption_policy(policy);
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_handshake_set(const std::string& value) {
|
||||
Policy policy = current_policy();
|
||||
apply_mode_value(policy, &Policy::handshake, value);
|
||||
apply_policy(policy);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
torrent::Object
|
||||
apply_stream_set(const std::string& value) {
|
||||
Policy policy = current_policy();
|
||||
apply_mode_value(policy, &Policy::stream, value);
|
||||
apply_policy(policy);
|
||||
return torrent::Object();
|
||||
}
|
||||
|
||||
void
|
||||
initialize_commands() {
|
||||
apply_policy(default_policy());
|
||||
|
||||
CMD2_ANY("protocol.encryption", [](auto, auto) { return summary_string(current_policy()); });
|
||||
|
||||
CMD2_ANY("protocol.encryption.handshake", [](auto, auto) { return mode_to_string(current_policy().handshake); });
|
||||
CMD2_ANY_STRING_V("protocol.encryption.handshake.set", [](auto, auto& str) { return apply_handshake_set(str); });
|
||||
|
||||
CMD2_ANY("protocol.encryption.stream", [](auto, auto) { return mode_to_string(current_policy().stream); });
|
||||
CMD2_ANY_STRING_V("protocol.encryption.stream.set", [](auto, auto& str) { return apply_stream_set(str); });
|
||||
|
||||
rpc::rpc.mark_safe("protocol.encryption");
|
||||
rpc::rpc.mark_safe("protocol.encryption.handshake");
|
||||
rpc::rpc.mark_safe("protocol.encryption.handshake.set");
|
||||
rpc::rpc.mark_safe("protocol.encryption.stream");
|
||||
rpc::rpc.mark_safe("protocol.encryption.stream.set");
|
||||
}
|
||||
|
||||
} // namespace encryption_config
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef RTORRENT_ENCRYPTION_CONFIG_H
|
||||
#define RTORRENT_ENCRYPTION_CONFIG_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include <torrent/runtime/encryption_policy.h>
|
||||
#include <torrent/object.h>
|
||||
|
||||
namespace encryption_config {
|
||||
|
||||
using Policy = torrent::EncryptionPolicy;
|
||||
|
||||
Policy default_policy();
|
||||
|
||||
std::string mode_to_string(Policy::Mode value);
|
||||
void apply_mode_value(Policy& policy, Policy::Mode Policy::*field, const std::string& value);
|
||||
|
||||
std::string summary_string(const Policy& policy);
|
||||
|
||||
void apply_policy(const Policy& policy);
|
||||
torrent::Object apply_handshake_set(const std::string& value);
|
||||
torrent::Object apply_stream_set(const std::string& value);
|
||||
|
||||
void initialize_commands();
|
||||
|
||||
} // namespace encryption_config
|
||||
|
||||
#endif
|
||||
@@ -13,7 +13,6 @@ void
|
||||
InputEvent::insert() {
|
||||
torrent::this_thread::poll()->open(this);
|
||||
torrent::this_thread::poll()->insert_read(this);
|
||||
torrent::this_thread::poll()->insert_error(this);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -11,7 +11,7 @@ class InputEvent : public torrent::Event {
|
||||
public:
|
||||
typedef std::function<void (int)> slot_int;
|
||||
|
||||
InputEvent(int fd) { m_fileDesc = fd; }
|
||||
InputEvent(int fd) { set_file_descriptor(fd); }
|
||||
|
||||
const char* type_name() const override { return "input"; }
|
||||
|
||||
|
||||
+25
-5
@@ -11,6 +11,9 @@
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/data/chunk_utils.h>
|
||||
#include <torrent/net/fd.h>
|
||||
#include <torrent/net/http_stack.h>
|
||||
#include <torrent/runtime/memory_manager.h>
|
||||
#include <torrent/runtime/runtime.h>
|
||||
#include <torrent/utils/chrono.h>
|
||||
#include <torrent/utils/log.h>
|
||||
|
||||
@@ -149,8 +152,8 @@ main(int argc, char** argv) {
|
||||
|
||||
SignalHandler::set_sigaction_handler(SIGBUS, &handle_sigbus);
|
||||
|
||||
torrent::log_add_group_output(torrent::LOG_NOTICE, "important");
|
||||
torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "important");
|
||||
torrent::log_add_group_output(torrent::LOG_NOTICE, "important");
|
||||
torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "important");
|
||||
|
||||
torrent::log_add_group_output(torrent::LOG_INFO, "complete");
|
||||
torrent::log_add_group_output(torrent::LOG_DHT_ERROR, "complete");
|
||||
@@ -298,7 +301,8 @@ main(int argc, char** argv) {
|
||||
"schedule = low_diskspace,5,60,((close_low_diskspace,500M))\n"
|
||||
"schedule = prune_file_status,3600,86400,((system.file_status_cache.prune))\n"
|
||||
|
||||
"protocol.encryption.set=allow_incoming,prefer_plaintext,enable_retry\n"
|
||||
"protocol.encryption.handshake.set=allow\n"
|
||||
"protocol.encryption.stream.set=allow\n"
|
||||
|
||||
"ui.color.focus.set=reverse\n"
|
||||
);
|
||||
@@ -318,8 +322,6 @@ main(int argc, char** argv) {
|
||||
CMD_REDIRECT("ratio.max.set", "group.seeding.ratio.max.set");
|
||||
CMD_REDIRECT("ratio.upload.set", "group.seeding.ratio.upload.set");
|
||||
|
||||
CMD_REDIRECT("encryption", "protocol.encryption.set");
|
||||
|
||||
CMD_REDIRECT("check_hash", "pieces.hash.on_completion.set");
|
||||
|
||||
CMD_REDIRECT("connection_leech", "protocol.connection.leech.set");
|
||||
@@ -417,6 +419,20 @@ main(int argc, char** argv) {
|
||||
lt_log_print(torrent::LOG_WARN, "The 'throttle.ip' command is deprecated and does nothing.");
|
||||
return torrent::Object();
|
||||
});
|
||||
|
||||
CMD_ANY("network.port_open", [](auto, auto) {
|
||||
lt_log_print(torrent::LOG_WARN, "The 'network.port_open' command is deprecated and does nothing.");
|
||||
return torrent::Object();
|
||||
});
|
||||
CMD_ANY("network.port_open.set", [](auto, auto) {
|
||||
lt_log_print(torrent::LOG_WARN, "The 'network.port_open.set' command is deprecated and does nothing.");
|
||||
return torrent::Object();
|
||||
});
|
||||
|
||||
CMD_REDIRECT("network.port_random", "network.listen.port.random");
|
||||
CMD_REDIRECT("network.port_random.set", "network.listen.port.random.set");
|
||||
CMD_REDIRECT("network.port_range", "network.listen.port.range");
|
||||
CMD_REDIRECT("network.port_range.set", "network.listen.port.range.set");
|
||||
}
|
||||
|
||||
{
|
||||
@@ -444,10 +460,14 @@ main(int argc, char** argv) {
|
||||
});
|
||||
|
||||
LT_LOG("seeded srandom and srand48 (seed:%u)", random_seed);
|
||||
LT_LOG("max memory usage: %" PRIu64, torrent::runtime::memory_manager()->max_memory_usage());
|
||||
|
||||
control->initialize();
|
||||
control->ui()->load_input_history();
|
||||
|
||||
torrent::net_thread::http_stack()->set_user_agent(USER_AGENT);
|
||||
torrent::runtime::initialize_network();
|
||||
|
||||
// Load session torrents and perform scheduled tasks to ensure session torrents are loaded
|
||||
// before arg torrents.
|
||||
control->dht_manager()->set_auto_if_untouched_and_has_session();
|
||||
|
||||
+15
-16
@@ -55,12 +55,11 @@ struct rt_triple : private std::pair<T1, T2> {
|
||||
base_type(src.first, src.second), third(src.third) {}
|
||||
};
|
||||
|
||||
typedef rt_triple<int, void*, void*> target_type;
|
||||
|
||||
class command_base;
|
||||
|
||||
typedef const torrent::Object (*command_base_call_type)(command_base*, target_type, const torrent::Object&);
|
||||
typedef std::function<torrent::Object (target_type, const torrent::Object&)> base_function;
|
||||
using target_type = rt_triple<int, void*, void*>;
|
||||
using base_function = std::function<torrent::Object (target_type, const torrent::Object&)>;
|
||||
using command_base_call_type = const torrent::Object (command_base*, target_type, const torrent::Object&);
|
||||
|
||||
template <typename tmpl> struct command_base_is_valid {};
|
||||
template <command_base_call_type tmpl_func> struct command_base_is_type {};
|
||||
@@ -84,17 +83,18 @@ public:
|
||||
|
||||
typedef const torrent::Object (*download_pair_slot) (command_base*, core::Download*, core::Download*, const torrent::Object&);
|
||||
|
||||
static const int target_generic = 0;
|
||||
static const int target_any = 1;
|
||||
static const int target_download = 2;
|
||||
static const int target_peer = 3;
|
||||
static const int target_tracker = 4;
|
||||
static const int target_file = 5;
|
||||
static const int target_file_itr = 6;
|
||||
static constexpr int target_generic = 0;
|
||||
static constexpr int target_any = 1;
|
||||
static constexpr int target_download = 2;
|
||||
static constexpr int target_peer = 3;
|
||||
static constexpr int target_tracker = 4;
|
||||
static constexpr int target_file = 5;
|
||||
static constexpr int target_file_itr = 6;
|
||||
static constexpr int target_download_pair = 7;
|
||||
|
||||
static const int target_download_pair = 7;
|
||||
static constexpr unsigned int max_arguments = 10;
|
||||
|
||||
static const unsigned int max_arguments = 10;
|
||||
static constexpr std::size_t optimal_alignment = std::max(alignof(std::max_align_t), alignof(base_function));
|
||||
|
||||
struct stack_type {
|
||||
torrent::Object* begin() { return reinterpret_cast<torrent::Object*>(buffer); }
|
||||
@@ -169,8 +169,7 @@ public:
|
||||
template <typename T>
|
||||
void set_function(T s, [[maybe_unused]] int value = command_base_is_valid<T>::value) {
|
||||
static_assert(sizeof(T) <= sizeof(t_pod), "t_pod storage overflow");
|
||||
static_assert(alignof(std::max_align_t) % alignof(T) == 0, "t_pod alignment insufficient for type");
|
||||
static_assert(alignof(std::max_align_t) >= alignof(T), "t_pod structural capacity mismatch");
|
||||
static_assert(optimal_alignment >= alignof(T), "t_pod alignment insufficient for type");
|
||||
|
||||
if (m_dest_helper)
|
||||
m_dest_helper(t_pod);
|
||||
@@ -200,7 +199,7 @@ protected:
|
||||
using copy_fn_t = void (*)(void* dest, const void* src);
|
||||
using dest_fn_t = void (*)(void* ptr);
|
||||
|
||||
alignas(std::max_align_t) char t_pod[sizeof(base_function)];
|
||||
alignas(optimal_alignment) char t_pod[sizeof(base_function)];
|
||||
|
||||
copy_fn_t m_copy_helper;
|
||||
dest_fn_t m_dest_helper;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <cstring>
|
||||
#include <fcntl.h>
|
||||
@@ -9,8 +10,8 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <torrent/net/fd.h>
|
||||
#include <torrent/system/system.h>
|
||||
#include <torrent/system/thread.h>
|
||||
#include <torrent/system/types.h>
|
||||
|
||||
#include "exec_file.h"
|
||||
#include "parse.h"
|
||||
@@ -24,6 +25,8 @@ namespace rpc {
|
||||
|
||||
int
|
||||
ExecFile::execute(const char* file, char* const* argv, int flags) {
|
||||
assert(!((flags & flag_capture) && (flags & flag_background)));
|
||||
|
||||
// Write the executed command and its parameters to the log fd.
|
||||
[[maybe_unused]] int result;
|
||||
|
||||
|
||||
@@ -111,7 +111,6 @@ SCgi::activate() {
|
||||
|
||||
torrent::this_thread::poll()->open(this);
|
||||
torrent::this_thread::poll()->insert_read(this);
|
||||
torrent::this_thread::poll()->insert_error(this);
|
||||
}
|
||||
|
||||
// TODO: This should close the fd to avoid reuse.
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace rpc {
|
||||
SCgiTask::SCgiTask()
|
||||
: m_callback_id(torrent::system::make_callback_id()) {
|
||||
|
||||
set_file_descriptor(-1);
|
||||
reset_file_descriptor();
|
||||
}
|
||||
|
||||
void
|
||||
@@ -49,7 +49,6 @@ SCgiTask::open(SCgi* parent, int fd) {
|
||||
|
||||
torrent::this_thread::poll()->open(this);
|
||||
torrent::this_thread::poll()->insert_read(this);
|
||||
torrent::this_thread::poll()->insert_error(this);
|
||||
|
||||
auto lock = std::lock_guard<std::mutex>(m_result_mutex);
|
||||
|
||||
@@ -65,7 +64,7 @@ SCgiTask::cancel_open() {
|
||||
torrent::this_thread::poll()->remove_and_close(this);
|
||||
|
||||
torrent::fd_close(file_descriptor());
|
||||
set_file_descriptor(-1);
|
||||
reset_file_descriptor();
|
||||
};
|
||||
|
||||
void
|
||||
@@ -79,7 +78,7 @@ SCgiTask::close() {
|
||||
torrent::this_thread::poll()->remove_and_close(this);
|
||||
|
||||
torrent::fd_close(file_descriptor());
|
||||
set_file_descriptor(-1);
|
||||
reset_file_descriptor();
|
||||
});
|
||||
|
||||
// The callbacks are guaranteed to be finished/canceled at this point.
|
||||
@@ -98,7 +97,7 @@ SCgiTask::event_read() {
|
||||
if (read_length <= 0)
|
||||
throw torrent::internal_error("SCgiTask::event_read() no space in buffer for event_read.");
|
||||
|
||||
int bytes = ::recv(m_fileDesc, m_buffer.data() + m_position, read_length, 0);
|
||||
int bytes = ::recv(file_descriptor(), m_buffer.data() + m_position, read_length, 0);
|
||||
|
||||
if (bytes <= 0) {
|
||||
if (bytes == 0 || !(errno == EAGAIN || errno == EINTR))
|
||||
@@ -181,7 +180,7 @@ event_read_failed:
|
||||
|
||||
void
|
||||
SCgiTask::event_write() {
|
||||
int bytes = ::send(m_fileDesc, m_buffer.data() + m_position, m_buffer.size() - m_position, 0);
|
||||
int bytes = ::send(file_descriptor(), m_buffer.data() + m_position, m_buffer.size() - m_position, 0);
|
||||
|
||||
if (bytes == -1) {
|
||||
if (!(errno == EAGAIN || errno == EINTR))
|
||||
|
||||
+2
-2
@@ -22,8 +22,8 @@ public:
|
||||
|
||||
const char* type_name() const override { return "scgi-task"; }
|
||||
|
||||
bool is_open() const { return m_fileDesc != -1; }
|
||||
bool is_available() const { return m_fileDesc == -1; }
|
||||
bool is_open() const { return file_descriptor() != -1; }
|
||||
bool is_available() const { return file_descriptor() == -1; }
|
||||
|
||||
void open(SCgi* parent, int fd);
|
||||
void cancel_open();
|
||||
|
||||
+4
-7
@@ -3,7 +3,6 @@
|
||||
#include <cassert>
|
||||
|
||||
#include <torrent/exceptions.h>
|
||||
#include <torrent/chunk_manager.h>
|
||||
#include <torrent/throttle.h>
|
||||
#include <torrent/torrent.h>
|
||||
#include <torrent/data/file_list.h>
|
||||
@@ -31,10 +30,10 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
Download::Download(core::Download* d) :
|
||||
m_download(d) {
|
||||
Download::Download(core::Download* d)
|
||||
: m_download(d) {
|
||||
|
||||
m_windowDownloadStatus = new WDownloadStatus(d);
|
||||
m_windowDownloadStatus = std::make_unique<WDownloadStatus>(d);
|
||||
m_windowDownloadStatus->set_bottom(true);
|
||||
|
||||
m_uiArray[DISPLAY_MENU] = create_menu();
|
||||
@@ -60,8 +59,6 @@ Download::~Download() {
|
||||
assert(!is_active() && "ui::Download::~Download() called on an active object.");
|
||||
|
||||
std::for_each(m_uiArray, m_uiArray + DISPLAY_MAX_SIZE, [](ElementBase* eb) { delete eb; });
|
||||
|
||||
delete m_windowDownloadStatus;
|
||||
}
|
||||
|
||||
inline ElementBase*
|
||||
@@ -171,7 +168,7 @@ Download::activate(display::Frame* frame, [[maybe_unused]] bool focus) {
|
||||
m_frame = frame;
|
||||
m_frame->initialize_row(2);
|
||||
|
||||
m_frame->frame(1)->initialize_window(m_windowDownloadStatus);
|
||||
m_frame->frame(1)->initialize_window(m_windowDownloadStatus.get());
|
||||
m_windowDownloadStatus->set_active(true);
|
||||
|
||||
activate_display_menu(DISPLAY_PEER_LIST);
|
||||
|
||||
+1
-35
@@ -1,37 +1,3 @@
|
||||
// rTorrent - BitTorrent client
|
||||
// Copyright (C) 2005-2011, Jari Sundell
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation; either version 2 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
//
|
||||
// In addition, as a special exception, the copyright holders give
|
||||
// permission to link the code of portions of this program with the
|
||||
// OpenSSL library under certain conditions as described in each
|
||||
// individual source file, and distribute linked combinations
|
||||
// including the two.
|
||||
//
|
||||
// You must obey the GNU General Public License in all respects for
|
||||
// all of the code used other than OpenSSL. If you modify file(s)
|
||||
// with this exception, you may extend this exception to your version
|
||||
// of the file(s), but you are not obligated to do so. If you do not
|
||||
// wish to do so, delete this exception statement from your version.
|
||||
// If you delete this exception statement from all source files in the
|
||||
// program, then also delete it here.
|
||||
//
|
||||
// Contact: Jari Sundell <sundell.software@gmail.com>
|
||||
|
||||
|
||||
#ifndef RTORRENT_UI_DOWNLOAD_H
|
||||
#define RTORRENT_UI_DOWNLOAD_H
|
||||
|
||||
@@ -113,7 +79,7 @@ private:
|
||||
|
||||
bool m_focusDisplay{};
|
||||
|
||||
WDownloadStatus* m_windowDownloadStatus;
|
||||
std::unique_ptr<WDownloadStatus> m_windowDownloadStatus;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -15,13 +15,13 @@ namespace ui {
|
||||
|
||||
class ElementLogComplete : public ElementBase {
|
||||
public:
|
||||
typedef display::WindowLogComplete WLogComplete;
|
||||
using WLogComplete = display::WindowLogComplete;
|
||||
|
||||
ElementLogComplete(torrent::log_buffer* l);
|
||||
~ElementLogComplete() override;
|
||||
|
||||
void activate(display::Frame* frame, bool focus = true);
|
||||
void disable();
|
||||
void activate(display::Frame* frame, bool focus = true) override;
|
||||
void disable() override;
|
||||
|
||||
display::Window* window();
|
||||
|
||||
@@ -32,7 +32,9 @@ private:
|
||||
|
||||
torrent::log_buffer* m_log;
|
||||
|
||||
align_cacheline std::atomic<bool> m_log_updating{};
|
||||
align_cacheline
|
||||
|
||||
std::atomic<bool> m_log_updating{};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ ElementPeerList::create_info() {
|
||||
element->push_column("Client:", te_command("p.client_version="));
|
||||
element->push_column("Options:", te_command("p.options_str="));
|
||||
element->push_column("Connected:", te_command("if=$p.is_incoming=,incoming,outgoing"));
|
||||
element->push_column("Encrypted:", te_command("if=$p.is_encrypted=,yes,$p.is_obfuscated=,handshake,no"));
|
||||
element->push_column("Encrypted:", te_command("if=$p.is_encrypted=,yes,$if=$p.is_obfuscated=\\,handshake\\,no"));
|
||||
|
||||
element->push_back("");
|
||||
element->push_column("Snubbed:", te_command("if=$p.is_snubbed=,yes,no"));
|
||||
|
||||
@@ -49,6 +49,8 @@ rtorrent_Test_Rpc_SOURCES = $(rtorrent_Test_Common) \
|
||||
rtorrent_Test_Src_SOURCES = $(rtorrent_Test_Common) \
|
||||
src/test_command_dynamic.cc \
|
||||
src/test_command_dynamic.h \
|
||||
src/test_encryption_config.cc \
|
||||
src/test_encryption_config.h \
|
||||
src/test_watch_ready_queue.cc \
|
||||
src/test_watch_ready_queue.h
|
||||
|
||||
|
||||
@@ -170,19 +170,18 @@ TestParseOptions::test_flag_libtorrent() {
|
||||
FLAG_LT_LOG_ASSERT_ERROR("resume_data|rpc_dump");
|
||||
}
|
||||
|
||||
#define FLAGS_LT_ENCRYPTION_ASSERT(flags, result) \
|
||||
CPPUNIT_ASSERT(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_ENCRYPTION, std::placeholders::_1)) == (result))
|
||||
#define FLAGS_LT_IP_TOS_ASSERT(flags, result) \
|
||||
CPPUNIT_ASSERT(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_IP_TOS, std::placeholders::_1)) == (result))
|
||||
|
||||
#define FLAGS_LT_ENCRYPTION_ASSERT_ERROR(flags) \
|
||||
ASSERT_CATCH_INPUT_ERROR(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_ENCRYPTION, std::placeholders::_1)))
|
||||
#define FLAGS_LT_IP_TOS_ASSERT_ERROR(flags) \
|
||||
ASSERT_CATCH_INPUT_ERROR(rpc::parse_option_flags(flags, std::bind(&torrent::option_find_string_str, torrent::OPTION_IP_TOS, std::placeholders::_1)))
|
||||
|
||||
void
|
||||
TestParseOptions::test_flags_libtorrent() {
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("", torrent::runtime::NetworkConfig::encryption_none);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("none", torrent::runtime::NetworkConfig::encryption_none);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_rc4", torrent::runtime::NetworkConfig::encryption_require_RC4);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_RC4", torrent::runtime::NetworkConfig::encryption_require_RC4);
|
||||
FLAGS_LT_ENCRYPTION_ASSERT("require_RC4 | enable_retry", torrent::runtime::NetworkConfig::encryption_require_RC4 | torrent::runtime::NetworkConfig::encryption_enable_retry);
|
||||
FLAGS_LT_IP_TOS_ASSERT("throughput", torrent::option_find_string(torrent::OPTION_IP_TOS, "throughput"));
|
||||
FLAGS_LT_IP_TOS_ASSERT("lowdelay | throughput",
|
||||
torrent::option_find_string(torrent::OPTION_IP_TOS, "lowdelay")
|
||||
| torrent::option_find_string(torrent::OPTION_IP_TOS, "throughput"));
|
||||
|
||||
FLAGS_LT_ENCRYPTION_ASSERT_ERROR("require_");
|
||||
FLAGS_LT_IP_TOS_ASSERT_ERROR("throughput_");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "test/src/test_encryption_config.h"
|
||||
|
||||
#include <torrent/runtime/encryption_policy.h>
|
||||
|
||||
#include "encryption_config.h"
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION(TestEncryptionConfig);
|
||||
|
||||
void
|
||||
TestEncryptionConfig::test_default_policy() {
|
||||
const auto policy = encryption_config::default_policy();
|
||||
|
||||
CPPUNIT_ASSERT(policy.handshake == encryption_config::Policy::Mode::allow);
|
||||
CPPUNIT_ASSERT(policy.stream == encryption_config::Policy::Mode::allow);
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("handshake=allow stream=allow"),
|
||||
encryption_config::summary_string(policy));
|
||||
}
|
||||
|
||||
void
|
||||
TestEncryptionConfig::test_granular_round_trip() {
|
||||
auto round_trip_handshake = [](const std::string& value) {
|
||||
encryption_config::Policy policy;
|
||||
encryption_config::apply_mode_value(policy, &encryption_config::Policy::handshake, value);
|
||||
return encryption_config::mode_to_string(policy.handshake);
|
||||
};
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("deny"), round_trip_handshake("deny"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("allow"), round_trip_handshake("allow"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("prefer"), round_trip_handshake("prefer"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("require"), round_trip_handshake("require"));
|
||||
|
||||
auto round_trip_stream = [](const std::string& value) {
|
||||
encryption_config::Policy policy;
|
||||
encryption_config::apply_mode_value(policy, &encryption_config::Policy::stream, value);
|
||||
return encryption_config::mode_to_string(policy.stream);
|
||||
};
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("deny"), round_trip_stream("deny"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("allow"), round_trip_stream("allow"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("prefer"), round_trip_stream("prefer"));
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("require"), round_trip_stream("require"));
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include "test/helpers/test_fixture.h"
|
||||
|
||||
class TestEncryptionConfig : public test_fixture {
|
||||
CPPUNIT_TEST_SUITE(TestEncryptionConfig);
|
||||
CPPUNIT_TEST(test_default_policy);
|
||||
CPPUNIT_TEST(test_granular_round_trip);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
void test_default_policy();
|
||||
void test_granular_round_trip();
|
||||
};
|
||||
Reference in New Issue
Block a user