summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2019-04-06 14:11:07 +0200
committerSébastien Helleu <flashcode@flashtux.org>2019-04-06 14:11:07 +0200
commita84c32cf30a369cd44d8ce7cc8df3277973051f1 (patch)
tree4f7dae7ce96f60fc63a277d0366a97f22f07abb5 /src/plugins
parent6ebd97cc63f7953d5ae78db6c1331184504e6b70 (diff)
downloadweechat-a84c32cf30a369cd44d8ce7cc8df3277973051f1.zip
xfer: add option xfer.network.speed_limit_recv (closes #269)
For consistency, the option xfer.network.speed_limit has been renamed to xfer.network.speed_limit_send.
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/xfer/xfer-config.c14
-rw-r--r--src/plugins/xfer/xfer-config.h3
-rw-r--r--src/plugins/xfer/xfer-dcc.c207
3 files changed, 130 insertions, 94 deletions
diff --git a/src/plugins/xfer/xfer-config.c b/src/plugins/xfer/xfer-config.c
index 9624dd61f..ddab21d82 100644
--- a/src/plugins/xfer/xfer-config.c
+++ b/src/plugins/xfer/xfer-config.c
@@ -50,7 +50,8 @@ struct t_config_option *xfer_config_network_fast_send;
struct t_config_option *xfer_config_network_own_ip;
struct t_config_option *xfer_config_network_port_range;
struct t_config_option *xfer_config_network_send_ack;
-struct t_config_option *xfer_config_network_speed_limit;
+struct t_config_option *xfer_config_network_speed_limit_send;
+struct t_config_option *xfer_config_network_speed_limit_recv;
struct t_config_option *xfer_config_network_timeout;
/* xfer config, file section */
@@ -294,13 +295,20 @@ xfer_config_init ()
"the acks are not sent immediately to the sender"),
NULL, 0, 0, "on", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
- xfer_config_network_speed_limit = weechat_config_new_option (
+ xfer_config_network_speed_limit_send = weechat_config_new_option (
xfer_config_file, ptr_section,
- "speed_limit", "integer",
+ "speed_limit_send", "integer",
N_("speed limit for sending files, in kilo-bytes by second (0 means "
"no limit)"),
NULL, 0, INT_MAX, "0", NULL, 0,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+ xfer_config_network_speed_limit_recv = weechat_config_new_option (
+ xfer_config_file, ptr_section,
+ "speed_limit_recv", "integer",
+ N_("speed limit for receiving files, in kilo-bytes by second (0 means "
+ "no limit)"),
+ NULL, 0, INT_MAX, "0", NULL, 0,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
xfer_config_network_timeout = weechat_config_new_option (
xfer_config_file, ptr_section,
"timeout", "integer",
diff --git a/src/plugins/xfer/xfer-config.h b/src/plugins/xfer/xfer-config.h
index f8f224a5a..2a31f0408 100644
--- a/src/plugins/xfer/xfer-config.h
+++ b/src/plugins/xfer/xfer-config.h
@@ -40,7 +40,8 @@ extern struct t_config_option *xfer_config_network_fast_send;
extern struct t_config_option *xfer_config_network_own_ip;
extern struct t_config_option *xfer_config_network_port_range;
extern struct t_config_option *xfer_config_network_send_ack;
-extern struct t_config_option *xfer_config_network_speed_limit;
+extern struct t_config_option *xfer_config_network_speed_limit_send;
+extern struct t_config_option *xfer_config_network_speed_limit_recv;
extern struct t_config_option *xfer_config_network_timeout;
extern struct t_config_option *xfer_config_file_auto_accept_chats;
diff --git a/src/plugins/xfer/xfer-dcc.c b/src/plugins/xfer/xfer-dcc.c
index 7b6f74033..13306c96d 100644
--- a/src/plugins/xfer/xfer-dcc.c
+++ b/src/plugins/xfer/xfer-dcc.c
@@ -49,11 +49,11 @@
void
xfer_dcc_send_file_child (struct t_xfer *xfer)
{
- int num_read, num_sent, blocksize;
+ int num_read, num_sent;
static char buffer[XFER_BLOCKSIZE_MAX];
uint32_t ack;
time_t last_sent, new_time, last_second, sent_ok;
- unsigned long long sent_last_second;
+ unsigned long long blocksize, speed_limit, sent_last_second;
/* empty file? just return immediately */
if (xfer->pos >= xfer->size)
@@ -63,15 +63,15 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
return;
}
- blocksize = xfer->blocksize;
- if (weechat_config_integer (xfer_config_network_speed_limit) > 0)
- {
- if (blocksize > weechat_config_integer (xfer_config_network_speed_limit) * 1024)
- blocksize = weechat_config_integer (xfer_config_network_speed_limit) * 1024;
- }
+ speed_limit = (unsigned long long)weechat_config_integer (
+ xfer_config_network_speed_limit_send);
+
+ blocksize = (unsigned long long)(xfer->blocksize);
+ if ((speed_limit > 0) && (blocksize > speed_limit * 1024))
+ blocksize = speed_limit * 1024;
last_sent = time (NULL);
- last_second = time (NULL);
+ last_second = last_sent;
sent_ok = 0;
sent_last_second = 0;
while (1)
@@ -113,8 +113,7 @@ xfer_dcc_send_file_child (struct t_xfer *xfer)
if ((xfer->pos < xfer->size) &&
(xfer->fast_send || (xfer->pos <= xfer->ack)))
{
- if ((weechat_config_integer (xfer_config_network_speed_limit) > 0)
- && (sent_last_second >= (unsigned long long)weechat_config_integer (xfer_config_network_speed_limit) * 1024))
+ if ((speed_limit > 0) && (sent_last_second >= speed_limit * 1024))
{
/* we're sending too fast (according to speed limit set by user) */
usleep (100);
@@ -311,13 +310,20 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
{
int flags, num_read, ready;
static char buffer[XFER_BLOCKSIZE_MAX];
- time_t last_sent, new_time;
- unsigned long long pos_last_ack;
+ time_t last_sent, last_second, new_time;
+ unsigned long long blocksize, pos_last_ack, speed_limit, recv_last_second;
struct pollfd poll_fd;
ssize_t written, total_written;
unsigned char *bin_hash;
char hash[9];
+ speed_limit = (unsigned long long)weechat_config_integer (
+ xfer_config_network_speed_limit_recv);
+
+ blocksize = sizeof (buffer);
+ if ((speed_limit > 0) && (blocksize > speed_limit * 1024))
+ blocksize = speed_limit * 1024;
+
/* if resuming, hash the portion of the file we have */
if ((xfer->start_resume > 0) && xfer->hash_handle)
{
@@ -361,6 +367,8 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
fcntl (xfer->sock, F_SETFL, flags | O_NONBLOCK);
last_sent = time (NULL);
+ last_second = last_sent;
+ recv_last_second = 0;
pos_last_ack = 0;
while (1)
@@ -385,114 +393,133 @@ xfer_dcc_recv_file_child (struct t_xfer *xfer)
/* read maximum data on socket (until nothing is available) */
while (1)
{
- num_read = recv (xfer->sock, buffer, sizeof (buffer), 0);
- if (num_read == -1)
+ if ((speed_limit > 0) && (recv_last_second >= speed_limit * 1024))
{
- if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR))
- {
- xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
- XFER_ERROR_RECV_BLOCK);
- return;
- }
/*
- * no more data available on socket: exit loop, send ACK, and
- * wait for new data on socket
+ * we're receiving too fast
+ * (according to speed limit set by user)
*/
- break;
+ usleep (100);
}
else
{
- if ((num_read == 0) && (xfer->pos < xfer->size))
+ num_read = recv (xfer->sock, buffer, blocksize, 0);
+ if (num_read == -1)
{
- xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
- XFER_ERROR_RECV_BLOCK);
- return;
+ if ((errno != EAGAIN) && (errno != EWOULDBLOCK) && (errno != EINTR))
+ {
+ xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
+ XFER_ERROR_RECV_BLOCK);
+ return;
+ }
+ /*
+ * no more data available on socket: exit loop, send ACK, and
+ * wait for new data on socket
+ */
+ break;
}
-
- /* bytes received, write to disk */
- total_written = 0;
- while (total_written < num_read)
+ else
{
- written = write (xfer->file,
- buffer + total_written,
- num_read - total_written);
- if (written < 0)
+ if ((num_read == 0) && (xfer->pos < xfer->size))
{
- if (errno == EINTR)
- continue;
xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
- XFER_ERROR_WRITE_LOCAL);
+ XFER_ERROR_RECV_BLOCK);
return;
}
- else
+
+ /* bytes received, write to disk */
+ total_written = 0;
+ while (total_written < num_read)
{
- if (xfer->hash_handle)
+ written = write (xfer->file,
+ buffer + total_written,
+ num_read - total_written);
+ if (written < 0)
{
- gcry_md_write (*xfer->hash_handle,
- buffer + total_written,
- written);
+ if (errno == EINTR)
+ continue;
+ xfer_network_write_pipe (xfer, XFER_STATUS_FAILED,
+ XFER_ERROR_WRITE_LOCAL);
+ return;
+ }
+ else
+ {
+ if (xfer->hash_handle)
+ {
+ gcry_md_write (*xfer->hash_handle,
+ buffer + total_written,
+ written);
+ }
+ total_written += written;
}
- total_written += written;
}
- }
- xfer->pos += (unsigned long long) num_read;
+ xfer->pos += (unsigned long long) num_read;
+ recv_last_second += (unsigned long long) num_read;
- /* file received OK? */
- if (xfer->pos >= xfer->size)
- {
- /* check hash and report result to pipe */
- if (xfer->hash_handle)
+ /* file received OK? */
+ if (xfer->pos >= xfer->size)
{
- gcry_md_final (*xfer->hash_handle);
- bin_hash = gcry_md_read (*xfer->hash_handle, 0);
- if (bin_hash)
+ /* check hash and report result to pipe */
+ if (xfer->hash_handle)
{
- snprintf (hash, sizeof (hash), "%.2X%.2X%.2X%.2X",
- bin_hash[0], bin_hash[1], bin_hash[2],
- bin_hash[3]);
- if (weechat_strcasecmp (hash,
- xfer->hash_target) == 0)
- {
- xfer_network_write_pipe (xfer,
- XFER_STATUS_HASHED,
- XFER_NO_ERROR);
- }
- else
+ gcry_md_final (*xfer->hash_handle);
+ bin_hash = gcry_md_read (*xfer->hash_handle, 0);
+ if (bin_hash)
{
- xfer_network_write_pipe (xfer,
- XFER_STATUS_HASHED,
- XFER_ERROR_HASH_MISMATCH);
+ snprintf (hash, sizeof (hash), "%.2X%.2X%.2X%.2X",
+ bin_hash[0], bin_hash[1], bin_hash[2],
+ bin_hash[3]);
+ if (weechat_strcasecmp (hash,
+ xfer->hash_target) == 0)
+ {
+ xfer_network_write_pipe (xfer,
+ XFER_STATUS_HASHED,
+ XFER_NO_ERROR);
+ }
+ else
+ {
+ xfer_network_write_pipe (xfer,
+ XFER_STATUS_HASHED,
+ XFER_ERROR_HASH_MISMATCH);
+ }
}
}
- }
- fsync (xfer->file);
+ fsync (xfer->file);
- /*
- * extra delay before sending ACK, otherwise the send of ACK
- * may fail
- */
- usleep (100000);
+ /*
+ * extra delay before sending ACK, otherwise the send of ACK
+ * may fail
+ */
+ usleep (100000);
- /* send ACK to sender without checking return code (file OK) */
- xfer_dcc_recv_file_send_ack (xfer);
+ /* send ACK to sender without checking return code (file OK) */
+ xfer_dcc_recv_file_send_ack (xfer);
- /* set status done and return */
- xfer_network_write_pipe (xfer, XFER_STATUS_DONE,
- XFER_NO_ERROR);
- return;
- }
+ /* set status done and return */
+ xfer_network_write_pipe (xfer, XFER_STATUS_DONE,
+ XFER_NO_ERROR);
+ return;
+ }
- /* update status of DCC (parent process) */
- new_time = time (NULL);
- if (last_sent != new_time)
- {
- last_sent = new_time;
- xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
- XFER_NO_ERROR);
+ /* update status of DCC (parent process) */
+ new_time = time (NULL);
+ if (last_sent != new_time)
+ {
+ last_sent = new_time;
+ xfer_network_write_pipe (xfer, XFER_STATUS_ACTIVE,
+ XFER_NO_ERROR);
+ }
}
}
+
+ new_time = time (NULL);
+ if (new_time > last_second)
+ {
+ last_second = new_time;
+ recv_last_second = 0;
+ }
}
/* send ACK to sender (if needed) */