diff --git a/btpd/Makefile.am b/btpd/Makefile.am index 718cfbd..0b4d4c8 100644 --- a/btpd/Makefile.am +++ b/btpd/Makefile.am @@ -8,9 +8,10 @@ btpd_SOURCES=\ net_buf.c net_buf.h\ queue.h \ peer.c peer.h\ - policy_choke.c policy_if.c policy_subr.c policy.h\ + download.c download_subr.c download.h\ torrent.c torrent.h\ - tracker_req.c tracker_req.h + tracker_req.c tracker_req.h\ + upload.c upload.h btpd_LDADD=../misc/libmisc.a -levent -lcrypto -lm btpd_CPPFLAGS=-I$(top_srcdir)/misc @event_CPPFLAGS@ @openssl_CPPFLAGS@ diff --git a/btpd/btpd.c b/btpd/btpd.c index 026bb26..0866d5a 100644 --- a/btpd/btpd.c +++ b/btpd/btpd.c @@ -37,7 +37,6 @@ struct child { BTPDQ_HEAD(child_tq, child); static uint8_t m_peer_id[20]; -static struct event m_heartbeat; static struct event m_sigint; static struct event m_sigterm; static struct event m_sigchld; @@ -45,8 +44,6 @@ static struct child_tq m_kids = BTPDQ_HEAD_INITIALIZER(m_kids); static unsigned m_ntorrents; static struct torrent_tq m_torrents = BTPDQ_HEAD_INITIALIZER(m_torrents); -unsigned long btpd_seconds; - void btpd_shutdown(void) { @@ -98,19 +95,6 @@ child_cb(int signal, short type, void *arg) } } -static void -heartbeat_cb(int sd, short type, void *arg) -{ - struct torrent *tp; - - btpd_seconds++; - - BTPDQ_FOREACH(tp, &m_torrents, entry) - dl_by_second(tp); - - evtimer_add(&m_heartbeat, (& (struct timeval) { 1, 0 })); -} - void btpd_add_torrent(struct torrent *tp) { @@ -165,6 +149,7 @@ btpd_init(void) net_init(); ipc_init(); + ul_init(); signal(SIGPIPE, SIG_IGN); @@ -174,7 +159,4 @@ btpd_init(void) signal_add(&m_sigterm, NULL); signal_set(&m_sigchld, SIGCHLD, child_cb, NULL); signal_add(&m_sigchld, NULL); - - evtimer_set(&m_heartbeat, heartbeat_cb, NULL); - evtimer_add(&m_heartbeat, (& (struct timeval) { 1, 0 })); } diff --git a/btpd/btpd.h b/btpd/btpd.h index 4b0a4a0..973976d 100644 --- a/btpd/btpd.h +++ b/btpd/btpd.h @@ -22,15 +22,14 @@ #include "net.h" #include "peer.h" #include "torrent.h" -#include "policy.h" +#include "download.h" +#include "upload.h" #include "subr.h" #include "opts.h" #define BTPD_VERSION (PACKAGE_NAME "/" PACKAGE_VERSION) -extern unsigned long btpd_seconds; - #define BTPD_L_ALL 0xffffffff #define BTPD_L_ERROR 0x00000001 #define BTPD_L_TRACKER 0x00000002 diff --git a/btpd/cli_if.c b/btpd/cli_if.c index a10d60b..99fcb82 100644 --- a/btpd/cli_if.c +++ b/btpd/cli_if.c @@ -38,7 +38,6 @@ cmd_stat(int argc, const char *args, FILE *fp) errdie(buf_swrite(&iob, "d")); errdie(buf_print(&iob, "6:npeersi%ue", net_npeers)); errdie(buf_print(&iob, "9:ntorrentsi%ue", btpd_get_ntorrents())); - errdie(buf_print(&iob, "7:secondsi%lue", btpd_seconds)); errdie(buf_swrite(&iob, "8:torrentsl")); BTPDQ_FOREACH(tp, btpd_get_torrents(), entry) { uint32_t seen_npieces = 0; diff --git a/btpd/policy_if.c b/btpd/download.c similarity index 79% rename from btpd/policy_if.c rename to btpd/download.c index 164e2a3..c093029 100644 --- a/btpd/policy_if.c +++ b/btpd/download.c @@ -4,19 +4,6 @@ #include "btpd.h" #include "tracker_req.h" -void -dl_by_second(struct torrent *tp) -{ - if (btpd_seconds == tp->tracker_time) - tracker_req(tp, TR_EMPTY); - - if (btpd_seconds == tp->opt_time) - next_optimistic(tp, NULL); - - if (btpd_seconds == tp->choke_time) - choke_alg(tp); -} - /* * Called when a peer announces it's got a new piece. * @@ -87,32 +74,6 @@ dl_on_choke(struct peer *p) dl_on_undownload(p); } -void -dl_on_upload(struct peer *p) -{ - choke_alg(p->tp); -} - -void -dl_on_interest(struct peer *p) -{ - if ((p->flags & PF_I_CHOKE) == 0) - dl_on_upload(p); -} - -void -dl_on_unupload(struct peer *p) -{ - choke_alg(p->tp); -} - -void -dl_on_uninterest(struct peer *p) -{ - if ((p->flags & PF_I_CHOKE) == 0) - dl_on_unupload(p); -} - /** * Called when a piece has been tested positively. */ @@ -181,20 +142,11 @@ void dl_on_new_peer(struct peer *p) { struct torrent *tp = p->tp; - tp->npeers++; p->flags |= PF_ATTACHED; BTPDQ_REMOVE(&net_unattached, p, p_entry); - - if (tp->npeers == 1) { - BTPDQ_INSERT_HEAD(&tp->peers, p, p_entry); - next_optimistic(tp, p); - } else { - if (random() > RAND_MAX / 3) - BTPDQ_INSERT_AFTER(&tp->peers, tp->optimistic, p, p_entry); - else - BTPDQ_INSERT_TAIL(&tp->peers, p, p_entry); - } + BTPDQ_INSERT_HEAD(&tp->peers, p, p_entry); + ul_on_new_peer(p); } void @@ -202,26 +154,15 @@ dl_on_lost_peer(struct peer *p) { struct torrent *tp = p->tp; + assert(tp->npeers > 0 && (p->flags & PF_ATTACHED) != 0); tp->npeers--; p->flags &= ~PF_ATTACHED; - if (tp->npeers == 0) { - BTPDQ_REMOVE(&tp->peers, p, p_entry); - tp->optimistic = NULL; - tp->choke_time = tp->opt_time = 0; - } else if (tp->optimistic == p) { - struct peer *next = BTPDQ_NEXT(p, p_entry); - BTPDQ_REMOVE(&tp->peers, p, p_entry); - next_optimistic(tp, next); - } else if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT) { - BTPDQ_REMOVE(&tp->peers, p, p_entry); - dl_on_unupload(p); - } else { - BTPDQ_REMOVE(&tp->peers, p, p_entry); - } + + ul_on_lost_peer(p); for (uint32_t i = 0; i < tp->meta.npieces; i++) - if (peer_has(p, i)) - tp->piece_count[i]--; + if (peer_has(p, i)) + tp->piece_count[i]--; if (p->nreqs_out > 0) dl_on_undownload(p); diff --git a/btpd/policy.h b/btpd/download.h similarity index 73% rename from btpd/policy.h rename to btpd/download.h index 5adf4a1..cbb83f5 100644 --- a/btpd/policy.h +++ b/btpd/download.h @@ -1,12 +1,7 @@ -#ifndef BTPD_POLICY_H -#define BTPD_POLICY_H +#ifndef BTPD_DOWNLOAD_H +#define BTPD_DOWNLOAD_H -// policy_choke.c - -void choke_alg(struct torrent *tp); -void next_optimistic(struct torrent *tp, struct peer *np); - -// policy_subr.c +// download_subr.c int piece_full(struct piece *pc); void piece_free(struct piece *pc); @@ -23,19 +18,13 @@ void dl_unassign_requests(struct peer *p); void dl_unassign_requests_eg(struct peer *p); void dl_piece_reorder_eg(struct piece *pc); -// policy_if.c - -void dl_by_second(struct torrent *tp); +// download.c void dl_on_new_peer(struct peer *p); void dl_on_lost_peer(struct peer *p); void dl_on_choke(struct peer *p); void dl_on_unchoke(struct peer *p); -void dl_on_upload(struct peer *p); -void dl_on_unupload(struct peer *p); -void dl_on_interest(struct peer *p); -void dl_on_uninterest(struct peer *p); void dl_on_download(struct peer *p); void dl_on_undownload(struct peer *p); void dl_on_piece_ann(struct peer *p, uint32_t index); diff --git a/btpd/policy_subr.c b/btpd/download_subr.c similarity index 100% rename from btpd/policy_subr.c rename to btpd/download_subr.c diff --git a/btpd/opts.h b/btpd/opts.h index d2d6460..cdf698f 100644 --- a/btpd/opts.h +++ b/btpd/opts.h @@ -1,3 +1,6 @@ +#ifndef BTPD_OPTS_H +#define BTPD_OPTS_H + extern short btpd_daemon; extern const char *btpd_dir; extern uint32_t btpd_logmask; @@ -5,3 +8,5 @@ extern unsigned net_max_peers; extern unsigned net_bw_limit_in; extern unsigned net_bw_limit_out; extern int net_port; + +#endif diff --git a/btpd/peer.c b/btpd/peer.c index 74bf7e8..10e18c9 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -383,7 +383,7 @@ peer_on_interest(struct peer *p) return; else { p->flags |= PF_P_WANT; - dl_on_interest(p); + ul_on_interest(p); } } @@ -395,7 +395,7 @@ peer_on_uninterest(struct peer *p) return; else { p->flags &= ~PF_P_WANT; - dl_on_uninterest(p); + ul_on_uninterest(p); } } diff --git a/btpd/peer.h b/btpd/peer.h index a25c73b..38b053c 100644 --- a/btpd/peer.h +++ b/btpd/peer.h @@ -61,7 +61,7 @@ struct peer { } net; BTPDQ_ENTRY(peer) p_entry; - + BTPDQ_ENTRY(peer) ul_entry; BTPDQ_ENTRY(peer) rq_entry; BTPDQ_ENTRY(peer) wq_entry; }; diff --git a/btpd/policy_choke.c b/btpd/policy_choke.c deleted file mode 100644 index 6da3ae3..0000000 --- a/btpd/policy_choke.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "btpd.h" - -static int -rate_cmp(long rate1, long rate2) -{ - if (rate1 < rate2) - return -1; - else if (rate1 == rate2) - return 0; - else - return 1; -} - -static int -dwnrate_cmp(const void *p1, const void *p2) -{ - long rate1 = (*(struct peer **)p1)->rate_dwn; - long rate2 = (*(struct peer **)p2)->rate_dwn; - return rate_cmp(rate1, rate2); -} - -static int -uprate_cmp(const void *p1, const void *p2) -{ - long rate1 = (*(struct peer **)p1)->rate_up; - long rate2 = (*(struct peer **)p2)->rate_up; - return rate_cmp(rate1, rate2); -} - -void -choke_alg(struct torrent *tp) -{ - assert(tp->npeers > 0); - - int i; - struct peer *p; - struct peer *psort[tp->npeers]; - - i = 0; - BTPDQ_FOREACH(p, &tp->peers, p_entry) - psort[i++] = p; - - if (tp->have_npieces == tp->meta.npieces) - qsort(psort, tp->npeers, sizeof(p), uprate_cmp); - else - qsort(psort, tp->npeers, sizeof(p), dwnrate_cmp); - - tp->ndown = 0; - if (tp->optimistic != NULL) { - if (tp->optimistic->flags & PF_I_CHOKE) - peer_unchoke(tp->optimistic); - if (tp->optimistic->flags & PF_P_WANT) - tp->ndown = 1; - } - - for (i = tp->npeers - 1; i >= 0; i--) { - if (psort[i] == tp->optimistic) - continue; - if (tp->ndown < 4) { - if (psort[i]->flags & PF_P_WANT) - tp->ndown++; - if (psort[i]->flags & PF_I_CHOKE) - peer_unchoke(psort[i]); - } else { - if ((psort[i]->flags & PF_I_CHOKE) == 0) - peer_choke(psort[i]); - } - } - - tp->choke_time = btpd_seconds + 10; -} - -void -next_optimistic(struct torrent *tp, struct peer *np) -{ - if (np != NULL) - tp->optimistic = np; - else if (tp->optimistic == NULL) - tp->optimistic = BTPDQ_FIRST(&tp->peers); - else { - np = BTPDQ_NEXT(tp->optimistic, p_entry); - if (np != NULL) - tp->optimistic = np; - else - tp->optimistic = BTPDQ_FIRST(&tp->peers); - } - assert(tp->optimistic != NULL); - choke_alg(tp); - tp->opt_time = btpd_seconds + 30; -} diff --git a/btpd/torrent.h b/btpd/torrent.h index f535b4c..5e0b935 100644 --- a/btpd/torrent.h +++ b/btpd/torrent.h @@ -52,10 +52,6 @@ struct torrent { uint64_t uploaded, downloaded; - unsigned long choke_time; - unsigned long opt_time; - unsigned long tracker_time; - short ndown; struct peer *optimistic; diff --git a/btpd/tracker_req.c b/btpd/tracker_req.c index 7f0a74b..32ad5a1 100644 --- a/btpd/tracker_req.c +++ b/btpd/tracker_req.c @@ -100,7 +100,7 @@ tracker_done(pid_t pid, void *arg) goto out; } - tp->tracker_time = btpd_seconds + interval; + //tp->tracker_time = btpd_seconds + interval; int error = 0; size_t length; @@ -134,7 +134,7 @@ out: "Start request failed for %s.\n", tp->relpath); torrent_unload(tp); } else - tp->tracker_time = btpd_seconds + 10; + ;//tp->tracker_time = btpd_seconds + 10; } munmap(req->res, REQ_SIZE); free(req); diff --git a/btpd/upload.c b/btpd/upload.c new file mode 100644 index 0000000..bc3af75 --- /dev/null +++ b/btpd/upload.c @@ -0,0 +1,72 @@ + +#include "btpd.h" + +static struct event m_choke_timer; +static unsigned m_npeers; +static struct peer_tq m_peerq = BTPDQ_HEAD_INITIALIZER(m_peerq); + +static void +choke_do(void) +{ + struct peer *p; + BTPDQ_FOREACH(p, &m_peerq, ul_entry) + if (p->flags & PF_I_CHOKE) + peer_unchoke(p); +} + +static void +choke_cb(int sd, short type, void *arg) +{ + evtimer_add(&m_choke_timer, (& (struct timeval) { 10, 0})); + choke_do(); +} + +void +ul_on_new_peer(struct peer *p) +{ + m_npeers++; + BTPDQ_INSERT_HEAD(&m_peerq, p, ul_entry); + choke_do(); +} + +void +ul_on_lost_peer(struct peer *p) +{ + assert(m_npeers > 0); + BTPDQ_REMOVE(&m_peerq, p, ul_entry); + m_npeers--; + if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT) + choke_do(); +} + +void +ul_on_lost_torrent(struct torrent *tp) +{ + struct peer *p; + BTPDQ_FOREACH(p, &tp->peers, p_entry) { + BTPDQ_REMOVE(&m_peerq, p, ul_entry); + m_npeers--; + } + choke_do(); +} + +void +ul_on_interest(struct peer *p) +{ + if ((p->flags & PF_I_CHOKE) == 0) + choke_do(); +} + +void +ul_on_uninterest(struct peer *p) +{ + if ((p->flags & PF_I_CHOKE) == 0) + choke_do(); +} + +void +ul_init(void) +{ + evtimer_set(&m_choke_timer, choke_cb, NULL); + evtimer_add(&m_choke_timer, (& (struct timeval) { 10, 0 })); +} diff --git a/btpd/upload.h b/btpd/upload.h new file mode 100644 index 0000000..49956ff --- /dev/null +++ b/btpd/upload.h @@ -0,0 +1,11 @@ +#ifndef BTPD_UPLOAD_H +#define BTPD_UPLOAD_H + +void ul_on_new_peer(struct peer *p); +void ul_on_lost_peer(struct peer *p); +void ul_on_lost_torrent(struct torrent *tp); +void ul_on_interest(struct peer *p); +void ul_on_uninterest(struct peer *p); +void ul_init(void); + +#endif