about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarq Schneider <queueRAM@gmail.com>2010-08-11 22:37:51 -0500
committerMarq Schneider <queueRAM@gmail.com>2010-08-11 22:37:51 -0500
commit64060294ab58dfd07a95a24a1500602421748da9 (patch)
treeec61cfce0fd1f4a7a8fa7c00168e38a1bd481ed3
parent033b776ab28e616fd9217087a50252297394a4ca (diff)
downloadbtpd-64060294ab58dfd07a95a24a1500602421748da9.tar.gz
btpd-64060294ab58dfd07a95a24a1500602421748da9.zip
Allow changing the upload and download rates at runtime.
This adds a 'rate' command to modify the up and download
rates on the fly.

Closes GH-10
-rw-r--r--Makefile.am2
-rw-r--r--btpd/cli_if.c28
-rw-r--r--btpd/upload.c8
-rw-r--r--btpd/upload.h1
-rw-r--r--cli/btcli.c2
-rw-r--r--cli/btcli.h2
-rw-r--r--cli/rate.c80
-rw-r--r--misc/btpd_if.c8
-rw-r--r--misc/btpd_if.h1
9 files changed, 130 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 0e8c56a..fb99eba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -32,7 +32,7 @@ cli_btinfo_SOURCES=cli/btinfo.c
 cli_btinfo_LDADD=misc/libmisc.a -lcrypto -lm
 
 # btcli
-cli_btcli_SOURCES=cli/btcli.c cli/btcli.h cli/add.c cli/del.c cli/list.c cli/kill.c cli/start.c cli/stop.c cli/stat.c
+cli_btcli_SOURCES=cli/btcli.c cli/btcli.h cli/add.c cli/del.c cli/list.c cli/rate.c cli/kill.c cli/start.c cli/stop.c cli/stat.c
 cli_btcli_LDADD=misc/libmisc.a -lcrypto -lm @INETLIBS@
 
 # libmisc
diff --git a/btpd/cli_if.c b/btpd/cli_if.c
index 7479035..c28382c 100644
--- a/btpd/cli_if.c
+++ b/btpd/cli_if.c
@@ -387,6 +387,33 @@ cmd_stop_all(struct cli *cli, int argc, const char *args)
 }
 
 static int
+cmd_rate(struct cli *cli, int argc, const char *args)
+{
+    unsigned up, down;
+
+    if (argc != 2)
+        return IPC_COMMERR;
+    if (btpd_is_stopping())
+        return write_code_buffer(cli, IPC_ESHUTDOWN);
+
+    if (benc_isint(args))
+        up = (unsigned)benc_int(args, &args);
+    else
+        return IPC_COMMERR;
+
+    if (benc_isint(args))
+        down = (unsigned)benc_int(args, &args);
+    else
+        return IPC_COMMERR;
+
+    net_bw_limit_out = up;
+    net_bw_limit_in  = down;
+    ul_set_max_uploads();
+
+    return write_code_buffer(cli, IPC_OK);
+}
+
+static int
 cmd_die(struct cli *cli, int argc, const char *args)
 {
     int err = write_code_buffer(cli, IPC_OK);
@@ -405,6 +432,7 @@ static struct {
     { "add",    3, cmd_add },
     { "del",    3, cmd_del },
     { "die",    3, cmd_die },
+    { "rate",   4, cmd_rate },
     { "start",  5, cmd_start },
     { "start-all", 9, cmd_start_all},
     { "stop",   4, cmd_stop },
diff --git a/btpd/upload.c b/btpd/upload.c
index ddde8a1..ec0e4e1 100644
--- a/btpd/upload.c
+++ b/btpd/upload.c
@@ -173,7 +173,7 @@ ul_on_uninterest(struct peer *p)
 }
 
 void
-ul_init(void)
+ul_set_max_uploads(void)
 {
     if (net_max_uploads >= -1)
         m_max_uploads = net_max_uploads;
@@ -189,6 +189,12 @@ ul_init(void)
         else
             m_max_uploads = 5 + (net_bw_limit_out / (100 << 10));
     }
+}
+
+void
+ul_init(void)
+{
+    ul_set_max_uploads();
 
     evtimer_init(&m_choke_timer, choke_cb, NULL);
     btpd_timer_add(&m_choke_timer, CHOKE_INTERVAL);
diff --git a/btpd/upload.h b/btpd/upload.h
index 43a8560..029cf16 100644
--- a/btpd/upload.h
+++ b/btpd/upload.h
@@ -6,6 +6,7 @@ void ul_on_lost_peer(struct peer *p);
 void ul_on_lost_torrent(struct net *n);
 void ul_on_interest(struct peer *p);
 void ul_on_uninterest(struct peer *p);
+void ul_set_max_uploads(void);
 void ul_init(void);
 
 #endif
diff --git a/cli/btcli.c b/cli/btcli.c
index bc1fb80..8d1aada 100644
--- a/cli/btcli.c
+++ b/cli/btcli.c
@@ -114,6 +114,7 @@ static struct {
     { "del", cmd_del, usage_del },
     { "kill", cmd_kill, usage_kill },
     { "list", cmd_list, usage_list },
+    { "rate", cmd_rate, usage_rate },
     { "start", cmd_start, usage_start },
     { "stop", cmd_stop, usage_stop },
     { "stat", cmd_stat, usage_stat }
@@ -141,6 +142,7 @@ usage(void)
         "del\t- Remove torrents from btpd.\n"
         "kill\t- Shut down btpd.\n"
         "list\t- List torrents.\n"
+        "rate\t- Set up/download rate limits.\n"
         "start\t- Activate torrents.\n"
         "stat\t- Display stats for active torrents.\n"
         "stop\t- Deactivate torrents.\n"
diff --git a/cli/btcli.h b/cli/btcli.h
index 19d360a..d0e0a28 100644
--- a/cli/btcli.h
+++ b/cli/btcli.h
@@ -45,6 +45,8 @@ void usage_stat(void);
 void cmd_stat(int argc, char **argv);
 void usage_kill(void);
 void cmd_kill(int argc, char **argv);
+void usage_rate(void);
+void cmd_rate(int argc, char **argv);
 void usage_start(void);
 void cmd_start(int argc, char **argv);
 void usage_stop(void);
diff --git a/cli/rate.c b/cli/rate.c
new file mode 100644
index 0000000..6e0a1bc
--- /dev/null
+++ b/cli/rate.c
@@ -0,0 +1,80 @@
+#include "btcli.h"
+
+void
+usage_rate(void)
+{
+    printf(
+        "Set upload and download rate.\n"
+        "\n"
+        "Usage: rate <up> <down>\n"
+        "\n"
+        "Arguments:\n"
+        "<up> <down>\n"
+        "\tThe up/down rate in KB/s\n"
+        "\n"
+        );
+    exit(1);
+}
+
+static struct option start_opts [] = {
+    { "help", no_argument, NULL, 'H' },
+    {NULL, 0, NULL, 0}
+};
+
+static unsigned
+parse_rate(char *rate)
+{
+    unsigned out;
+    char *end;
+
+    out = strtol(rate, &end, 10);
+    if (end == rate)
+        usage_rate();
+
+    if ((end[0] != '\0') && (end[1] != '\0'))
+        usage_rate();
+
+    switch(end[0]) {
+        case 'g':
+        case 'G':
+            out <<= 30;
+            break;
+        case 'm':
+        case 'M':
+            out <<= 20;
+            break;
+        case '\0': /* default is 'k' */
+        case 'k':
+        case 'K':
+            out <<= 10;
+            break;
+        case 'b':
+        case 'B':
+            break;
+        default:
+            usage_rate();
+    }
+    return out;
+}
+
+void
+cmd_rate(int argc, char **argv)
+{
+    int ch;
+    unsigned up, down;
+
+    while ((ch = getopt_long(argc, argv, "", start_opts, NULL)) != -1)
+        usage_rate();
+    argc -= optind;
+    argv += optind;
+
+    if (argc < 2)
+        usage_rate();
+
+    up = parse_rate(argv[0]);
+    down = parse_rate(argv[1]);
+
+    btpd_connect();
+    handle_ipc_res(btpd_rate(ipc, up, down), "rate", argv[1]);
+}
+
diff --git a/misc/btpd_if.c b/misc/btpd_if.c
index b661b21..e208d64 100644
--- a/misc/btpd_if.c
+++ b/misc/btpd_if.c
@@ -297,6 +297,14 @@ btpd_del(struct ipc *ipc, struct ipc_torrent *tp)
 }
 
 enum ipc_err
+btpd_rate(struct ipc *ipc, unsigned up, unsigned down)
+{
+    struct iobuf iob = iobuf_init(32);
+    iobuf_print(&iob, "l4:ratei%iei%iee", up, down);
+    return ipc_buf_req_code(ipc, &iob);
+}
+
+enum ipc_err
 btpd_start(struct ipc *ipc, struct ipc_torrent *tp)
 {
     return simple_treq(ipc, "start", tp);
diff --git a/misc/btpd_if.h b/misc/btpd_if.h
index 3bf77d1..66b247a 100644
--- a/misc/btpd_if.h
+++ b/misc/btpd_if.h
@@ -77,6 +77,7 @@ const char *ipc_strerror(enum ipc_err err);
 enum ipc_err btpd_add(struct ipc *ipc, const char *mi, size_t mi_size,
     const char *content, const char *name);
 enum ipc_err btpd_del(struct ipc *ipc, struct ipc_torrent *tp);
+enum ipc_err btpd_rate(struct ipc *ipc, unsigned up, unsigned down);
 enum ipc_err btpd_start(struct ipc *ipc, struct ipc_torrent *tp);
 enum ipc_err btpd_start_all(struct ipc *ipc);
 enum ipc_err btpd_stop(struct ipc *ipc, struct ipc_torrent *tp);