diff --git a/btpd/Makefile.am b/btpd/Makefile.am index ab67b5e..ca0a096 100644 --- a/btpd/Makefile.am +++ b/btpd/Makefile.am @@ -1,7 +1,7 @@ bin_PROGRAMS=btpd btpd_SOURCES=\ btpd.c btpd.h\ - content.c content.h\ + cli_if.c content.c content.h\ download.c download_subr.c download.h\ http.c http.h\ main.c\ diff --git a/btpd/btpd.c b/btpd/btpd.c index 1ecbae8..161c780 100644 --- a/btpd/btpd.c +++ b/btpd/btpd.c @@ -216,7 +216,7 @@ btpd_init(void) td_init(); http_init(); net_init(); - //ipc_init(); + ipc_init(); ul_init(); cm_init(); diff --git a/btpd/cli_if.c b/btpd/cli_if.c index dd24858..9b699f3 100644 --- a/btpd/cli_if.c +++ b/btpd/cli_if.c @@ -36,20 +36,27 @@ cmd_stat(int argc, const char *args, FILE *fp) errdie(buf_print(&iob, "9:ntorrentsi%ue", btpd_get_ntorrents())); errdie(buf_swrite(&iob, "8:torrentsl")); BTPDQ_FOREACH(tp, btpd_get_torrents(), entry) { + if (tp->state != T_ACTIVE) + continue; + uint32_t seen_npieces = 0; for (uint32_t i = 0; i < tp->meta.npieces; i++) - if (tp->piece_count[i] > 0) + if (tp->net->piece_count[i] > 0) seen_npieces++; - errdie(buf_print(&iob, "d4:downi%jue", (intmax_t)tp->downloaded)); + errdie(buf_print(&iob, "d4:downi%jue", (intmax_t)tp->net->downloaded)); errdie(buf_swrite(&iob, "4:hash20:")); errdie(buf_write(&iob, tp->meta.info_hash, 20)); - errdie(buf_print(&iob, "12:have npiecesi%ue", tp->have_npieces)); - errdie(buf_print(&iob, "6:npeersi%ue", tp->npeers)); + errdie(buf_print(&iob, "4:havei%jde", (intmax_t)cm_get_size(tp))); + errdie(buf_print(&iob, "6:npeersi%ue", tp->net->npeers)); errdie(buf_print(&iob, "7:npiecesi%ue", tp->meta.npieces)); errdie(buf_print(&iob, "4:path%d:%s", (int)strlen(tp->relpath), tp->relpath)); + errdie(buf_print(&iob, "2:rdi%lue", tp->net->rate_dwn)); + errdie(buf_print(&iob, "2:rui%lue", tp->net->rate_up)); errdie(buf_print(&iob, "12:seen npiecesi%ue", seen_npieces)); - errdie(buf_print(&iob, "2:upi%juee", (intmax_t)tp->uploaded)); + errdie(buf_print(&iob, "5:totali%jde", + (intmax_t)tp->meta.total_length)); + errdie(buf_print(&iob, "2:upi%juee", (intmax_t)tp->net->uploaded)); } errdie(buf_swrite(&iob, "ee")); @@ -59,6 +66,7 @@ cmd_stat(int argc, const char *args, FILE *fp) free(iob.buf); } +#if 0 static void cmd_add(int argc, const char *args, FILE *fp) { @@ -144,15 +152,18 @@ cmd_die(int argc, const char *args, FILE *fp) btpd_log(BTPD_L_BTPD, "Someone wants me dead.\n"); btpd_shutdown(); } +#endif static struct { const char *name; int nlen; void (*fun)(int, const char *, FILE *); } cmd_table[] = { +#if 0 { "add", 3, cmd_add }, { "del", 3, cmd_del }, { "die", 3, cmd_die }, +#endif { "stat", 4, cmd_stat } }; diff --git a/btpd/main.c b/btpd/main.c index ba6361b..000757d 100644 --- a/btpd/main.c +++ b/btpd/main.c @@ -61,8 +61,13 @@ setup_daemon(const char *dir) err(1, "Couldn't create library"); pidfd = open("pid", O_CREAT|O_WRONLY|O_NONBLOCK|O_EXLOCK, 0666); - if (pidfd == -1) - err(1, "Couldn't open 'pid'"); + if (pidfd == -1) { + if (errno == EAGAIN) + errx(1, "Another instance of btpd is probably running in %s.", + dir); + else + err(1, "Couldn't open 'pid'"); + } if (btpd_daemon) { if (daemon(1, 1) != 0) @@ -82,6 +87,10 @@ static void usage(void) { printf("Usage: btpd [options] [dir]\n" + "\n" + "dir:\n" + "\tThe directory in which to run btpd.\n" + "\tDefault is '$HOME/.btpd'.\n" "\n" "Options:\n" "\n" @@ -97,11 +106,22 @@ usage(void) "\tKeep the btpd process in the foregorund and log to std{out,err}.\n" "\tThis option is intended for debugging purposes.\n" "\n" + "--downloaders n\n" + "\tControls the number of simultaneous uploads.\n" + "\tThe possible values are:\n" + "\t\tn < -1 : Choose n >= 2 based on --bw-out (default).\n" + "\t\tn = -1 : Upload to every interested peer.\n" + "\t\tn = 0 : Dont't upload to anyone.\n" + "\t\tn > 0 : Upload to at most n peers simultaneosly.\n" + "\n" + "--max-peers n\n" + "\tLimit the amount of peers to n.\n" + "\n" "-p n, --port n\n" "\tListen at port n. Default is 6881.\n" "\n" "--prealloc n\n" - "\tPreallocate disk space in chunks n kB. Default is 1.\n" + "\tPreallocate disk space in chunks of n kB. Default is 1.\n" "\tNote that n will be rounded up to the closest multiple of the\n" "\ttorrent piece size. If n is zero no preallocation will be done.\n" "\n" @@ -118,7 +138,9 @@ static struct option longopts[] = { { "bw-in", required_argument, &longval, 1 }, { "bw-out", required_argument, &longval, 2 }, { "prealloc", required_argument, &longval, 3 }, - { "help", no_argument, &longval, 5 }, + { "downloaders", required_argument, &longval, 4 }, + { "max-peers", required_argument, &longval, 5 }, + { "help", no_argument, &longval, 128 }, { NULL, 0, NULL, 0 } }; @@ -150,6 +172,12 @@ main(int argc, char **argv) case 3: cm_alloc_size = atoi(optarg) * 1024; break; + case 4: + net_max_downloaders = atoi(optarg); + break; + case 5: + net_max_peers = atoi(optarg); + break; default: usage(); } diff --git a/btpd/net.c b/btpd/net.c index c728efd..43b43f8 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -626,16 +626,9 @@ net_init(void) m_bw_bytes_out = net_bw_limit_out; m_bw_bytes_in = net_bw_limit_in; - int nfiles = getdtablesize(); - if (nfiles <= 20) - btpd_err("Too few open files allowed (%d). " - "Check \"ulimit -n\"\n", nfiles); - else if (nfiles < 64) - btpd_log(BTPD_L_BTPD, - "You have restricted the number of open files to %d. " - "More could be beneficial to the download performance.\n", - nfiles); - net_max_peers = nfiles - 20; + int safe_fds = min(getdtablesize(), FD_SETSIZE) * 4 / 5; + if (net_max_peers == 0 || net_max_peers > safe_fds) + net_max_peers = safe_fds; int sd; int flag = 1; diff --git a/btpd/opts.c b/btpd/opts.c index 9c68678..7321727 100644 --- a/btpd/opts.c +++ b/btpd/opts.c @@ -7,6 +7,7 @@ uint32_t btpd_logmask = BTPD_L_ALL; #else uint32_t btpd_logmask = BTPD_L_BTPD | BTPD_L_ERROR; #endif +int net_max_downloaders = -2; unsigned net_max_peers; unsigned net_bw_limit_in; unsigned net_bw_limit_out; diff --git a/btpd/opts.h b/btpd/opts.h index 98e2dbd..c47ea63 100644 --- a/btpd/opts.h +++ b/btpd/opts.h @@ -4,6 +4,7 @@ extern short btpd_daemon; extern const char *btpd_dir; extern uint32_t btpd_logmask; +extern int net_max_downloaders; extern unsigned net_max_peers; extern unsigned net_bw_limit_in; extern unsigned net_bw_limit_out; diff --git a/btpd/upload.c b/btpd/upload.c index c812881..f8403ad 100644 --- a/btpd/upload.c +++ b/btpd/upload.c @@ -7,7 +7,7 @@ static struct event m_choke_timer; static unsigned m_npeers; static struct peer_tq m_peerq = BTPDQ_HEAD_INITIALIZER(m_peerq); -static int m_max_downloaders = 4; +static int m_max_downloaders; struct peer_sort { struct peer *p; @@ -32,7 +32,7 @@ rate_cmp(const void *arg1, const void *arg2) static void choke_do(void) { - if (m_max_downloaders == -1) { + if (m_max_downloaders < 0) { struct peer *p; BTPDQ_FOREACH(p, &m_peerq, ul_entry) if (p->flags & PF_I_CHOKE) @@ -42,7 +42,7 @@ choke_do(void) BTPDQ_FOREACH(p, &m_peerq, ul_entry) if ((p->flags & PF_I_CHOKE) == 0) peer_choke(p); - } else if (m_npeers > 0) { + } else { struct peer_sort worthy[m_npeers]; int nworthy = 0; int i = 0; @@ -171,6 +171,21 @@ ul_on_uninterest(struct peer *p) void ul_init(void) { + if (net_max_downloaders >= -1) + m_max_downloaders = net_max_downloaders; + else { + if (net_bw_limit_out == 0) + m_max_downloaders = 8; + else if (net_bw_limit_out < (10 << 10)) + m_max_downloaders = 2; + else if (net_bw_limit_out < (20 << 10)) + m_max_downloaders = 3; + else if (net_bw_limit_out < (40 << 10)) + m_max_downloaders = 4; + else + m_max_downloaders = 5 + (net_bw_limit_out / (100 << 10)); + } + evtimer_set(&m_choke_timer, choke_cb, NULL); evtimer_add(&m_choke_timer, CHOKE_INTERVAL); }