From 64060294ab58dfd07a95a24a1500602421748da9 Mon Sep 17 00:00:00 2001 From: Marq Schneider Date: Wed, 11 Aug 2010 22:37:51 -0500 Subject: [PATCH] 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 --- Makefile.am | 2 +- btpd/cli_if.c | 28 ++++++++++++++++++ btpd/upload.c | 8 ++++- btpd/upload.h | 1 + cli/btcli.c | 2 ++ cli/btcli.h | 2 ++ cli/rate.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ misc/btpd_if.c | 8 +++++ misc/btpd_if.h | 1 + 9 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 cli/rate.c 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 @@ -386,6 +386,33 @@ cmd_stop_all(struct cli *cli, int argc, const char *args) return ret; } +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) { @@ -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 \n" + "\n" + "Arguments:\n" + " \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 @@ -296,6 +296,14 @@ btpd_del(struct ipc *ipc, struct ipc_torrent *tp) return simple_treq(ipc, "del", 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) { 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);