diff options
| -rw-r--r-- | btpd/Makefile.am | 2 | ||||
| -rw-r--r-- | btpd/btpd.c | 34 | ||||
| -rw-r--r-- | btpd/btpd.h | 2 | ||||
| -rw-r--r-- | btpd/download.c | 32 | ||||
| -rw-r--r-- | btpd/download.h | 1 | ||||
| -rw-r--r-- | btpd/download_subr.c | 95 | ||||
| -rw-r--r-- | btpd/main.c | 5 | ||||
| -rw-r--r-- | btpd/net.c | 2 | ||||
| -rw-r--r-- | btpd/net_buf.c | 9 | ||||
| -rw-r--r-- | btpd/peer.c | 23 | ||||
| -rw-r--r-- | btpd/torrent.c | 246 | ||||
| -rw-r--r-- | btpd/torrent.h | 41 | ||||
| -rw-r--r-- | btpd/tracker_req.c | 15 | ||||
| -rw-r--r-- | btpd/upload.c | 8 |
14 files changed, 165 insertions, 350 deletions
diff --git a/btpd/Makefile.am b/btpd/Makefile.am index 0b4d4c8..0c04f36 100644 --- a/btpd/Makefile.am +++ b/btpd/Makefile.am @@ -3,11 +3,11 @@ btpd_SOURCES=\ main.c util.c\ btpd.c btpd.h\ opts.c opts.h\ - cli_if.c\ net.c net.h\ net_buf.c net_buf.h\ queue.h \ peer.c peer.h\ + content.c content.h\ download.c download_subr.c download.h\ torrent.c torrent.h\ tracker_req.c tracker_req.h\ diff --git a/btpd/btpd.c b/btpd/btpd.c index 6775595..516602e 100644 --- a/btpd/btpd.c +++ b/btpd/btpd.c @@ -52,7 +52,7 @@ btpd_shutdown(void) tp = BTPDQ_FIRST(&m_torrents); while (tp != NULL) { struct torrent *next = BTPDQ_NEXT(tp, entry); - torrent_unload(tp); + torrent_deactivate(tp); tp = next; } btpd_log(BTPD_L_BTPD, "Exiting.\n"); @@ -136,6 +136,30 @@ btpd_get_peer_id(void) return m_peer_id; } +static int +nodot(struct dirent *dp) +{ + return !(strcmp(".", dp->d_name) == 0 || strcmp("..", dp->d_name) == 0); +} + +static void +load_library(void) +{ + int ne; + struct dirent **entries; + if ((ne = scandir("library", &entries, nodot, NULL)) < 0) + btpd_err("Couldn't open the library.\n"); + + for (int i = 0; i < ne; i++) { + struct torrent *tp; + struct dirent *e = entries[i]; + if (torrent_create(&tp, e->d_name) == 0) + btpd_add_torrent(tp); + free(e); + } + free(entries); +} + extern void ipc_init(void); void @@ -148,9 +172,15 @@ btpd_init(void) m_peer_id[i] = rand_between(0, 255); net_init(); - ipc_init(); + //ipc_init(); ul_init(); + load_library(); + + struct torrent *tp; + BTPDQ_FOREACH(tp, &m_torrents, entry) + torrent_activate(tp); + signal(SIGPIPE, SIG_IGN); signal_set(&m_sigint, SIGINT, signal_cb, NULL); diff --git a/btpd/btpd.h b/btpd/btpd.h index 06d5925..68aaa0b 100644 --- a/btpd/btpd.h +++ b/btpd/btpd.h @@ -25,7 +25,7 @@ #include "download.h" #include "upload.h" #include "subr.h" - +#include "content.h" #include "opts.h" #define BTPD_VERSION (PACKAGE_NAME "/" PACKAGE_VERSION) diff --git a/btpd/download.c b/btpd/download.c index fd7f680..c2ff7f6 100644 --- a/btpd/download.c +++ b/btpd/download.c @@ -1,5 +1,4 @@ -#include <sys/types.h> -#include <sys/mman.h> +#include <math.h> #include "btpd.h" #include "tracker_req.h" @@ -7,6 +6,10 @@ void dl_start(struct torrent *tp) { + BTPDQ_INIT(&tp->getlst); + tp->busy_field = btpd_calloc((size_t)ceil(tp->meta.npieces / 8.0), 1); + tp->piece_count = btpd_calloc(tp->meta.npieces, + sizeof(*(tp->piece_count))); } void @@ -15,6 +18,8 @@ dl_stop(struct torrent *tp) struct piece *pc; while ((pc = BTPDQ_FIRST(&tp->getlst)) != NULL) piece_free(pc); + free(tp->busy_field); + free(tp->piece_count); } /* @@ -28,7 +33,7 @@ dl_on_piece_ann(struct peer *p, uint32_t index) { struct torrent *tp = p->tp; tp->piece_count[index]++; - if (has_bit(tp->piece_field, index)) + if (cm_has_piece(tp, index)) return; struct piece *pc = dl_find_piece(tp, index); if (tp->endgame) { @@ -98,10 +103,6 @@ dl_on_ok_piece(struct piece *pc) btpd_log(BTPD_L_POL, "Got piece: %u.\n", pc->index); - set_bit(tp->piece_field, pc->index); - tp->have_npieces++; - msync(tp->imem, tp->isiz, MS_ASYNC); - struct net_buf *have = nb_create_have(pc->index); BTPDQ_FOREACH(p, &tp->peers, p_entry) peer_send(p, have); @@ -114,7 +115,7 @@ dl_on_ok_piece(struct piece *pc) assert(pc->nreqs == 0); piece_free(pc); - if (torrent_has_all(tp)) { + if (cm_full(tp)) { btpd_log(BTPD_L_BTPD, "Finished: %s.\n", tp->relpath); tracker_req(tp, TR_COMPLETED); BTPDQ_FOREACH(p, &tp->peers, p_entry) @@ -133,13 +134,11 @@ dl_on_bad_piece(struct piece *pc) btpd_log(BTPD_L_ERROR, "Bad hash for piece %u of %s.\n", pc->index, tp->relpath); - for (uint32_t i = 0; i < pc->nblocks; i++) { + for (uint32_t i = 0; i < pc->nblocks; i++) clear_bit(pc->down_field, i); - clear_bit(pc->have_field, i); - } + pc->ngot = 0; pc->nbusy = 0; - msync(tp->imem, tp->isiz, MS_ASYNC); if (tp->endgame) { struct peer *p; @@ -177,10 +176,7 @@ dl_on_block(struct peer *p, struct block_request *req, struct block *blk = req->blk; struct piece *pc = blk->pc; - off_t cbegin = index * p->tp->meta.piece_length + begin; - torrent_put_bytes(p->tp, data, cbegin, length); - - set_bit(pc->have_field, begin / PIECE_BLOCKLEN); + cm_put_block(p->tp, index, begin / PIECE_BLOCKLEN, data); pc->ngot++; if (tp->endgame) { @@ -204,7 +200,7 @@ dl_on_block(struct peer *p, struct block_request *req, } BTPDQ_INIT(&blk->reqs); if (pc->ngot == pc->nblocks) - dl_on_piece(pc); + cm_test_piece(pc); } else { BTPDQ_REMOVE(&blk->reqs, req, blk_entry); free(req); @@ -213,7 +209,7 @@ dl_on_block(struct peer *p, struct block_request *req, clear_bit(pc->down_field, begin / PIECE_BLOCKLEN); pc->nbusy--; if (pc->ngot == pc->nblocks) - dl_on_piece(pc); + cm_test_piece(pc); if (peer_leech_ok(p) && !peer_laden(p)) dl_assign_requests(p); } diff --git a/btpd/download.h b/btpd/download.h index a4ae402..94f71da 100644 --- a/btpd/download.h +++ b/btpd/download.h @@ -7,7 +7,6 @@ int piece_full(struct piece *pc); void piece_free(struct piece *pc); void dl_on_piece_unfull(struct piece *pc); -void dl_on_piece(struct piece *pc); struct piece *dl_new_piece(struct torrent *tp, uint32_t index); struct piece *dl_find_piece(struct torrent *tp, uint32_t index); diff --git a/btpd/download_subr.c b/btpd/download_subr.c index f77d7db..f1db9a7 100644 --- a/btpd/download_subr.c +++ b/btpd/download_subr.c @@ -47,9 +47,7 @@ piece_alloc(struct torrent *tp, uint32_t index) pc = btpd_calloc(1, mem); pc->tp = tp; pc->down_field = (uint8_t *)(pc + 1); - pc->have_field = - tp->block_field + - index * (size_t)ceil(tp->meta.piece_length / (double)(1 << 17)); + pc->have_field = cm_get_block_field(tp, index); pc->index = index; pc->nblocks = nblocks; @@ -60,6 +58,7 @@ piece_alloc(struct torrent *tp, uint32_t index) for (unsigned i = 0; i < nblocks; i++) if (has_bit(pc->have_field, i)) pc->ngot++; + assert(pc->ngot < pc->nblocks); pc->blocks = (struct block *)(pc->down_field + field); for (unsigned i = 0; i < nblocks; i++) { @@ -108,7 +107,7 @@ static int dl_should_enter_endgame(struct torrent *tp) { int should; - if (tp->have_npieces + tp->npcs_busy == tp->meta.npieces) { + if (cm_get_npieces(tp) + tp->npcs_busy == tp->meta.npieces) { should = 1; struct piece *pc; BTPDQ_FOREACH(pc, &tp->getlst, entry) { @@ -196,78 +195,9 @@ dl_find_piece(struct torrent *tp, uint32_t index) } static int -test_hash(struct torrent *tp, uint8_t *hash, unsigned long index) -{ - if (tp->meta.piece_hash != NULL) - return memcmp(hash, tp->meta.piece_hash[index], SHA_DIGEST_LENGTH); - else { - char piece_hash[SHA_DIGEST_LENGTH]; - int fd; - int bufi; - int err; - - err = vopen(&fd, O_RDONLY, "%s/torrent", tp->relpath); - if (err != 0) - btpd_err("test_hash: %s\n", strerror(err)); - - err = lseek(fd, tp->meta.pieces_off + index * SHA_DIGEST_LENGTH, - SEEK_SET); - if (err < 0) - btpd_err("test_hash: %s\n", strerror(errno)); - - bufi = 0; - while (bufi < SHA_DIGEST_LENGTH) { - ssize_t nread = - read(fd, piece_hash + bufi, SHA_DIGEST_LENGTH - bufi); - bufi += nread; - } - close(fd); - - return memcmp(hash, piece_hash, SHA_DIGEST_LENGTH); - } -} - -static int -ro_fd_cb(const char *path, int *fd, void *arg) -{ - struct torrent *tp = arg; - return vopen(fd, O_RDONLY, "%s/content/%s", tp->relpath, path); -} - -static void -torrent_test_piece(struct piece *pc) -{ - struct torrent *tp = pc->tp; - int err; - uint8_t hash[20]; - struct bt_stream_ro *bts; - off_t plen = torrent_piece_size(tp, pc->index); - - if ((bts = bts_open_ro(&tp->meta, pc->index * tp->meta.piece_length, - ro_fd_cb, tp)) == NULL) - btpd_err("Out of memory.\n"); - - if ((err = bts_sha(bts, plen, hash)) != 0) - btpd_err("Ouch! %s\n", strerror(err)); - - bts_close_ro(bts); - - if (test_hash(tp, hash, pc->index) == 0) - dl_on_ok_piece(pc); - else - dl_on_bad_piece(pc); -} - -void -dl_on_piece(struct piece *pc) -{ - torrent_test_piece(pc); -} - -static int dl_piece_startable(struct peer *p, uint32_t index) { - return peer_has(p, index) && !has_bit(p->tp->piece_field, index) + return peer_has(p, index) && !cm_has_piece(p->tp, index) && !has_bit(p->tp->busy_field, index); } @@ -319,10 +249,9 @@ dl_choose_rarest(struct peer *p, uint32_t *res) } /* - * Called from either dl_piece_assign_requests or dl_new_piece, - * when a pice becomes full. The wanted level of the peers - * that has this piece will be decreased. This function is - * the only one that may trigger end game. + * Called from dl_piece_assign_requests when a piece becomes full. + * The wanted level of the peers that has this piece will be decreased. + * This function is the only one that may trigger end game. */ static void dl_on_piece_full(struct piece *pc) @@ -349,15 +278,7 @@ struct piece * dl_new_piece(struct torrent *tp, uint32_t index) { btpd_log(BTPD_L_POL, "Started on piece %u.\n", index); - struct piece *pc = piece_alloc(tp, index); - if (pc->ngot == pc->nblocks) { - dl_on_piece_full(pc); - dl_on_piece(pc); - if (dl_should_enter_endgame(tp)) - dl_enter_endgame(tp); - return NULL; - } else - return pc; + return piece_alloc(tp, index); } /* diff --git a/btpd/main.c b/btpd/main.c index c41d6b2..fe5f9ba 100644 --- a/btpd/main.c +++ b/btpd/main.c @@ -57,6 +57,9 @@ setup_daemon(const char *dir) if (chdir(dir) != 0) err(1, "Couldn't change working directory to '%s'", dir); + if (mkdir("library", 0777) == -1 && errno != EEXIST) + 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'"); @@ -170,9 +173,9 @@ args_done: event_init(); btpd_init(); - torrent_load("test"); event_dispatch(); + btpd_err("Unexpected exit from libevent.\n"); return 1; diff --git a/btpd/net.c b/btpd/net.c index cf42df5..8b7ebfc 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -208,7 +208,7 @@ net_dispatch_msg(struct peer *p, const char *buf) length = net_read32(buf + 8); if ((length > PIECE_BLOCKLEN || index >= p->tp->meta.npieces - || !has_bit(p->tp->piece_field, index) + || cm_has_piece(p->tp, index) || begin + length > torrent_piece_size(p->tp, index))) { btpd_log(BTPD_L_MSG, "bad request: (%u, %u, %u) from %p\n", index, begin, length, p); diff --git a/btpd/net_buf.c b/btpd/net_buf.c index 2402e01..880d94f 100644 --- a/btpd/net_buf.c +++ b/btpd/net_buf.c @@ -121,9 +121,10 @@ nb_create_have(uint32_t index) struct net_buf * nb_create_multihave(struct torrent *tp) { - struct net_buf *out = nb_create_alloc(NB_MULTIHAVE, 9 * tp->have_npieces); - for (uint32_t i = 0, count = 0; count < tp->have_npieces; i++) { - if (has_bit(tp->piece_field, i)) { + uint32_t have_npieces = cm_get_npieces(tp); + struct net_buf *out = nb_create_alloc(NB_MULTIHAVE, 9 * have_npieces); + for (uint32_t i = 0, count = 0; count < have_npieces; i++) { + if (cm_has_piece(tp, i)) { net_write32(out->buf + count * 9, 5); out->buf[count * 9 + 4] = MSG_HAVE; net_write32(out->buf + count * 9 + 5, i); @@ -183,7 +184,7 @@ nb_create_bitdata(struct torrent *tp) { uint32_t plen = ceil(tp->meta.npieces / 8.0); struct net_buf *out = - nb_create_set(NB_BITDATA, tp->piece_field, plen, kill_buf_no); + nb_create_set(NB_BITDATA, cm_get_piece_field(tp), plen, kill_buf_no); return out; } diff --git a/btpd/peer.c b/btpd/peer.c index c7273ff..3367512 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -336,8 +336,8 @@ peer_on_shake(struct peer *p) printid[i] = '\0'; btpd_log(BTPD_L_MSG, "received shake(%s) from %p\n", printid, p); p->piece_field = btpd_calloc(1, (int)ceil(p->tp->meta.npieces / 8.0)); - if (p->tp->have_npieces > 0) { - if (p->tp->have_npieces * 9 < 5 + ceil(p->tp->meta.npieces / 8.0)) + if (cm_get_npieces(p->tp) > 0) { + if (cm_get_npieces(p->tp) * 9 < 5 + ceil(p->tp->meta.npieces / 8.0)) peer_send(p, nb_create_multihave(p->tp)); else { peer_send(p, nb_create_bitfield(p->tp)); @@ -467,15 +467,16 @@ peer_on_request(struct peer *p, uint32_t index, uint32_t begin, btpd_log(BTPD_L_MSG, "received request(%u,%u,%u) from %p\n", index, begin, length, p); if ((p->flags & PF_NO_REQUESTS) == 0) { - off_t cbegin = index * p->tp->meta.piece_length + begin; - char * content = torrent_get_bytes(p->tp, cbegin, length); - peer_send(p, nb_create_piece(index, begin, length)); - peer_send(p, nb_create_torrentdata(content, length)); - p->npiece_msgs++; - if (p->npiece_msgs >= MAXPIECEMSGS) { - peer_send(p, nb_create_choke()); - peer_send(p, nb_create_unchoke()); - p->flags |= PF_NO_REQUESTS; + char *content; + if (cm_get_bytes(p->tp, index, begin, length, &content) == 0) { + peer_send(p, nb_create_piece(index, begin, length)); + peer_send(p, nb_create_torrentdata(content, length)); + p->npiece_msgs++; + if (p->npiece_msgs >= MAXPIECEMSGS) { + peer_send(p, nb_create_choke()); + peer_send(p, nb_create_unchoke()); + p->flags |= PF_NO_REQUESTS; + } } } } diff --git a/btpd/torrent.c b/btpd/torrent.c index 850e229..f317e67 100644 --- a/btpd/torrent.c +++ b/btpd/torrent.c @@ -19,194 +19,6 @@ #include "tracker_req.h" #include "stream.h" -static int -ro_fd_cb(const char *path, int *fd, void *arg) -{ - struct torrent *tp = arg; - return vopen(fd, O_RDONLY, "%s/content/%s", tp->relpath, path); -} - -static int -wo_fd_cb(const char *path, int *fd, void *arg) -{ - struct torrent *tp = arg; - return vopen(fd, O_WRONLY|O_CREAT, "%s/content/%s", tp->relpath, path); -} - -static int -torrent_load3(const char *file, struct metainfo *mi, char *mem, size_t memsiz) -{ - struct torrent *tp = btpd_calloc(1, sizeof(*tp)); - - tp->relpath = strdup(file); - if (tp->relpath == NULL) - btpd_err("Out of memory.\n"); - - tp->piece_count = btpd_calloc(mi->npieces, sizeof(tp->piece_count[0])); - tp->busy_field = btpd_calloc(ceil(mi->npieces / 8.0), 1); - - BTPDQ_INIT(&tp->peers); - BTPDQ_INIT(&tp->getlst); - - tp->imem = mem; - tp->isiz = memsiz; - - tp->piece_field = tp->imem; - tp->block_field = - (uint8_t *)tp->imem + (size_t)ceil(mi->npieces / 8.0); - - for (uint32_t i = 0; i < mi->npieces; i++) - if (has_bit(tp->piece_field, i)) - tp->have_npieces++; - - tp->meta = *mi; - free(mi); - - btpd_add_torrent(tp); - net_add_torrent(tp); - - tracker_req(tp, TR_STARTED); - - return 0; -} - -static int -torrent_load2(const char *name, struct metainfo *mi) -{ - int error, ifd; - struct stat sb; - char *mem; - size_t memsiz; - const char *file = name; - - if ((error = vopen(&ifd, O_RDWR, "%s/resume", file)) != 0) { - btpd_log(BTPD_L_ERROR, "Error opening %s.i: %s.\n", - file, strerror(error)); - return error; - } - - if (fstat(ifd, &sb) == -1) { - error = errno; - btpd_log(BTPD_L_ERROR, "Error stating %s.i: %s.\n", - file, strerror(error)); - close(ifd); - return error; - } - - memsiz = - ceil(mi->npieces / 8.0) + - mi->npieces * ceil(mi->piece_length / (double)(1 << 17)); - - if (sb.st_size != memsiz) { - btpd_log(BTPD_L_ERROR, "File has wrong size: %s.i.\n", file); - close(ifd); - return EINVAL; - } - - mem = mmap(NULL, memsiz, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); - if (mem == MAP_FAILED) - btpd_err("Error mmap'ing %s.i: %s.\n", file, strerror(errno)); - - close(ifd); - - if ((error = torrent_load3(file, mi, mem, memsiz) != 0)) { - munmap(mem, memsiz); - return error; - } - - return 0; -} - -int -torrent_load(const char *name) -{ - struct metainfo *mi; - int error; - char file[PATH_MAX]; - snprintf(file, PATH_MAX, "%s/torrent", name); - - if ((error = load_metainfo(file, -1, 0, &mi)) != 0) { - btpd_log(BTPD_L_ERROR, "Couldn't load metainfo file %s: %s.\n", - file, strerror(error)); - return error; - } - - if (btpd_get_torrent(mi->info_hash) != NULL) { - btpd_log(BTPD_L_BTPD, "%s has same hash as an already loaded torrent.\n", file); - error = EEXIST; - } - - if (error == 0) - error = torrent_load2(name, mi); - - if (error != 0) { - clear_metainfo(mi); - free(mi); - } - - return error; -} - -void -torrent_unload(struct torrent *tp) -{ - btpd_log(BTPD_L_BTPD, "Unloading %s.\n", tp->relpath); - - net_del_torrent(tp); - - tracker_req(tp, TR_STOPPED); - - free(tp->piece_count); - free(tp->busy_field); - free((void *)tp->relpath); - clear_metainfo(&tp->meta); - - munmap(tp->imem, tp->isiz); - - btpd_del_torrent(tp); - free(tp); -} - -off_t -torrent_bytes_left(struct torrent *tp) -{ - if (tp->have_npieces == 0) - return tp->meta.total_length; - else if (has_bit(tp->piece_field, tp->meta.npieces - 1)) { - return tp->meta.total_length - - ((tp->have_npieces - 1) * tp->meta.piece_length + - tp->meta.total_length % tp->meta.piece_length); - } else - return tp->meta.total_length - - tp->have_npieces * tp->meta.piece_length; -} - -char * -torrent_get_bytes(struct torrent *tp, off_t start, size_t len) -{ - char *buf = btpd_malloc(len); - struct bt_stream_ro *bts; - if ((bts = bts_open_ro(&tp->meta, start, ro_fd_cb, tp)) == NULL) - btpd_err("Out of memory.\n"); - if (bts_read_ro(bts, buf, len) != 0) - btpd_err("Io error.\n"); - bts_close_ro(bts); - return buf; -} - -void -torrent_put_bytes(struct torrent *tp, const char *buf, off_t start, size_t len) -{ - int err; - struct bt_stream_wo *bts; - if ((bts = bts_open_wo(&tp->meta, start, wo_fd_cb, tp)) == NULL) - btpd_err("Out of memory.\n"); - if ((err = bts_write_wo(bts, buf, len)) != 0) - btpd_err("Io error1: %s\n", strerror(err)); - if ((err = bts_close_wo(bts)) != 0) - btpd_err("Io error2: %s\n", strerror(err)); -} - int torrent_has_peer(struct torrent *tp, const uint8_t *id) { @@ -244,8 +56,62 @@ torrent_block_size(struct piece *pc, uint32_t index) } } +void +torrent_activate(struct torrent *tp) +{ + assert(tp->state == T_INACTIVE); + tp->state = T_STARTING; + cm_start(tp); +} + +void +torrent_deactivate(struct torrent *tp) +{ + +} + int -torrent_has_all(struct torrent *tp) +torrent_create(struct torrent **res, const char *path) { - return tp->have_npieces == tp->meta.npieces; + struct metainfo *mi; + int error; + char file[PATH_MAX]; + snprintf(file, PATH_MAX, "library/%s/torrent", path); + + if ((error = load_metainfo(file, -1, 0, &mi)) != 0) { + btpd_log(BTPD_L_ERROR, "Couldn't load metainfo file %s: %s.\n", + file, strerror(error)); + return error; + } + + if (btpd_get_torrent(mi->info_hash) != NULL) { + btpd_log(BTPD_L_BTPD, + "%s has same hash as an already loaded torrent.\n", path); + error = EEXIST; + } + + if (error == 0) { + *res = btpd_calloc(1, sizeof(**res)); + (*res)->relpath = strdup(path); + (*res)->meta = *mi; + free(mi); + } else { + clear_metainfo(mi); + free(mi); + } + + return error; +} + +void torrent_cm_cb(struct torrent *tp, enum cm_state state) +{ + switch (state) { + case CM_STARTED: + net_add_torrent(tp); + tracker_req(tp, TR_STARTED); + case CM_STOPPED: + abort(); + case CM_ERROR: + abort(); + } } diff --git a/btpd/torrent.h b/btpd/torrent.h index cb3be8e..1797a73 100644 --- a/btpd/torrent.h +++ b/btpd/torrent.h @@ -23,7 +23,7 @@ struct piece { struct block *blocks; - uint8_t *have_field; + const uint8_t *have_field; uint8_t *down_field; BTPDQ_ENTRY(piece) entry; @@ -31,26 +31,29 @@ struct piece { BTPDQ_HEAD(piece_tq, piece); +enum torrent_state { + T_INACTIVE, + T_STARTING, + T_ACTIVE, + T_STOPPING +}; + struct torrent { const char *relpath; struct metainfo meta; + enum torrent_state state; + + struct content *cp; + BTPDQ_ENTRY(torrent) entry; BTPDQ_ENTRY(torrent) net_entry; - void *imem; - size_t isiz; - int net_active; - uint8_t *piece_field; - uint8_t *block_field; - uint8_t *busy_field; uint32_t npcs_busy; - uint32_t have_npieces; - unsigned *piece_count; uint64_t uploaded, downloaded; @@ -66,21 +69,21 @@ struct torrent { BTPDQ_HEAD(torrent_tq, torrent); -off_t torrent_bytes_left(struct torrent *tp); - -char *torrent_get_bytes(struct torrent *tp, off_t start, size_t len); -void torrent_put_bytes(struct torrent *tp, const char *buf, - off_t start, size_t len); - -int torrent_load(const char *metafile); - -void torrent_unload(struct torrent *tp); +int torrent_create(struct torrent **res, const char *path); +void torrent_activate(struct torrent *tp); +void torrent_deactivate(struct torrent *tp); int torrent_has_peer(struct torrent *tp, const uint8_t *id); off_t torrent_piece_size(struct torrent *tp, uint32_t index); uint32_t torrent_block_size(struct piece *pc, uint32_t index); -int torrent_has_all(struct torrent *tp); +enum cm_state { + CM_STARTED, + CM_STOPPED, + CM_ERROR +}; + +void torrent_cm_cb(struct torrent *tp, enum cm_state state); #endif diff --git a/btpd/tracker_req.c b/btpd/tracker_req.c index 55d5669..e059b04 100644 --- a/btpd/tracker_req.c +++ b/btpd/tracker_req.c @@ -128,14 +128,9 @@ tracker_done(pid_t pid, void *arg) } out: - if (failed) { - if (req->tr_event == TR_STARTED) { - btpd_log(BTPD_L_BTPD, - "Start request failed for %s.\n", tp->relpath); - torrent_unload(tp); - } else - ;//tp->tracker_time = btpd_seconds + 10; - } + if (failed) + ;//tp->tracker_time = btpd_seconds + 10; + munmap(req->res, REQ_SIZE); free(req); } @@ -165,7 +160,7 @@ create_url(struct tracker_req *req, struct torrent *tp, char **url) const uint8_t *peer_id = btpd_get_peer_id(); char qc; int i; - uint64_t left; + off_t left; const char *event; event = event2str(req->tr_event); @@ -178,7 +173,7 @@ create_url(struct tracker_req *req, struct torrent *tp, char **url) for (i = 0; i < 20; i++) snprintf(e_id + i * 3, 4, "%%%.2x", peer_id[i]); - left = torrent_bytes_left(tp); + left = cm_bytes_left(tp); i = asprintf(url, "%s%cinfo_hash=%s" "&peer_id=%s" diff --git a/btpd/upload.c b/btpd/upload.c index 5ae7f1b..5e5174d 100644 --- a/btpd/upload.c +++ b/btpd/upload.c @@ -19,8 +19,8 @@ rate_cmp(const void *arg1, const void *arg2) { struct peer *p1 = (*(struct peer_sort **)arg1)->p; struct peer *p2 = (*(struct peer_sort **)arg2)->p; - unsigned long rate1 = torrent_has_all(p1->tp) ? p1->rate_up : p1->rate_dwn; - unsigned long rate2 = torrent_has_all(p2->tp) ? p2->rate_up : p2->rate_dwn; + unsigned long rate1 = cm_full(p1->tp) ? p1->rate_up : p1->rate_dwn; + unsigned long rate2 = cm_full(p2->tp) ? p2->rate_up : p2->rate_dwn; if (rate1 < rate2) return -1; else if (rate1 == rate2) @@ -51,8 +51,8 @@ choke_do(void) int unchoked[m_npeers]; BTPDQ_FOREACH(p, &m_peerq, ul_entry) { - if (((torrent_has_all(p->tp) && p->rate_up > 0) - || (!torrent_has_all(p->tp) && p->rate_dwn > 0))) { + if (((cm_full(p->tp) && p->rate_up > 0) + || (!cm_full(p->tp) && p->rate_dwn > 0))) { worthy[nworthy].p = p; worthy[nworthy].i = i; nworthy++; |