This adds a 'rate' command to modify the up and download rates on the fly. Closes GH-10master
@@ -32,7 +32,7 @@ cli_btinfo_SOURCES=cli/btinfo.c | |||||
cli_btinfo_LDADD=misc/libmisc.a -lcrypto -lm | cli_btinfo_LDADD=misc/libmisc.a -lcrypto -lm | ||||
# btcli | # 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@ | cli_btcli_LDADD=misc/libmisc.a -lcrypto -lm @INETLIBS@ | ||||
# libmisc | # libmisc | ||||
@@ -386,6 +386,33 @@ cmd_stop_all(struct cli *cli, int argc, const char *args) | |||||
return ret; | 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 | static int | ||||
cmd_die(struct cli *cli, int argc, const char *args) | cmd_die(struct cli *cli, int argc, const char *args) | ||||
{ | { | ||||
@@ -405,6 +432,7 @@ static struct { | |||||
{ "add", 3, cmd_add }, | { "add", 3, cmd_add }, | ||||
{ "del", 3, cmd_del }, | { "del", 3, cmd_del }, | ||||
{ "die", 3, cmd_die }, | { "die", 3, cmd_die }, | ||||
{ "rate", 4, cmd_rate }, | |||||
{ "start", 5, cmd_start }, | { "start", 5, cmd_start }, | ||||
{ "start-all", 9, cmd_start_all}, | { "start-all", 9, cmd_start_all}, | ||||
{ "stop", 4, cmd_stop }, | { "stop", 4, cmd_stop }, | ||||
@@ -173,7 +173,7 @@ ul_on_uninterest(struct peer *p) | |||||
} | } | ||||
void | void | ||||
ul_init(void) | |||||
ul_set_max_uploads(void) | |||||
{ | { | ||||
if (net_max_uploads >= -1) | if (net_max_uploads >= -1) | ||||
m_max_uploads = net_max_uploads; | m_max_uploads = net_max_uploads; | ||||
@@ -189,6 +189,12 @@ ul_init(void) | |||||
else | else | ||||
m_max_uploads = 5 + (net_bw_limit_out / (100 << 10)); | 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); | evtimer_init(&m_choke_timer, choke_cb, NULL); | ||||
btpd_timer_add(&m_choke_timer, CHOKE_INTERVAL); | btpd_timer_add(&m_choke_timer, CHOKE_INTERVAL); | ||||
@@ -6,6 +6,7 @@ void ul_on_lost_peer(struct peer *p); | |||||
void ul_on_lost_torrent(struct net *n); | void ul_on_lost_torrent(struct net *n); | ||||
void ul_on_interest(struct peer *p); | void ul_on_interest(struct peer *p); | ||||
void ul_on_uninterest(struct peer *p); | void ul_on_uninterest(struct peer *p); | ||||
void ul_set_max_uploads(void); | |||||
void ul_init(void); | void ul_init(void); | ||||
#endif | #endif |
@@ -114,6 +114,7 @@ static struct { | |||||
{ "del", cmd_del, usage_del }, | { "del", cmd_del, usage_del }, | ||||
{ "kill", cmd_kill, usage_kill }, | { "kill", cmd_kill, usage_kill }, | ||||
{ "list", cmd_list, usage_list }, | { "list", cmd_list, usage_list }, | ||||
{ "rate", cmd_rate, usage_rate }, | |||||
{ "start", cmd_start, usage_start }, | { "start", cmd_start, usage_start }, | ||||
{ "stop", cmd_stop, usage_stop }, | { "stop", cmd_stop, usage_stop }, | ||||
{ "stat", cmd_stat, usage_stat } | { "stat", cmd_stat, usage_stat } | ||||
@@ -141,6 +142,7 @@ usage(void) | |||||
"del\t- Remove torrents from btpd.\n" | "del\t- Remove torrents from btpd.\n" | ||||
"kill\t- Shut down btpd.\n" | "kill\t- Shut down btpd.\n" | ||||
"list\t- List torrents.\n" | "list\t- List torrents.\n" | ||||
"rate\t- Set up/download rate limits.\n" | |||||
"start\t- Activate torrents.\n" | "start\t- Activate torrents.\n" | ||||
"stat\t- Display stats for active torrents.\n" | "stat\t- Display stats for active torrents.\n" | ||||
"stop\t- Deactivate torrents.\n" | "stop\t- Deactivate torrents.\n" | ||||
@@ -45,6 +45,8 @@ void usage_stat(void); | |||||
void cmd_stat(int argc, char **argv); | void cmd_stat(int argc, char **argv); | ||||
void usage_kill(void); | void usage_kill(void); | ||||
void cmd_kill(int argc, char **argv); | void cmd_kill(int argc, char **argv); | ||||
void usage_rate(void); | |||||
void cmd_rate(int argc, char **argv); | |||||
void usage_start(void); | void usage_start(void); | ||||
void cmd_start(int argc, char **argv); | void cmd_start(int argc, char **argv); | ||||
void usage_stop(void); | void usage_stop(void); | ||||
@@ -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]); | |||||
} | |||||
@@ -296,6 +296,14 @@ btpd_del(struct ipc *ipc, struct ipc_torrent *tp) | |||||
return simple_treq(ipc, "del", 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 | enum ipc_err | ||||
btpd_start(struct ipc *ipc, struct ipc_torrent *tp) | btpd_start(struct ipc *ipc, struct ipc_torrent *tp) | ||||
{ | { | ||||
@@ -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, | enum ipc_err btpd_add(struct ipc *ipc, const char *mi, size_t mi_size, | ||||
const char *content, const char *name); | const char *content, const char *name); | ||||
enum ipc_err btpd_del(struct ipc *ipc, struct ipc_torrent *tp); | 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(struct ipc *ipc, struct ipc_torrent *tp); | ||||
enum ipc_err btpd_start_all(struct ipc *ipc); | enum ipc_err btpd_start_all(struct ipc *ipc); | ||||
enum ipc_err btpd_stop(struct ipc *ipc, struct ipc_torrent *tp); | enum ipc_err btpd_stop(struct ipc *ipc, struct ipc_torrent *tp); | ||||