Explorar el Código

o Use the new cm_* content api.

o Unhook cli_if.c from build temporarily. It needs to be fixed.
o Torrent meta data is now kept in subdirectories to $BTPD_HOME/library.
o Added some very incomplete life cycle logic for torrents.
master
Richard Nyberg hace 19 años
padre
commit
49e90df57e
Se han modificado 14 ficheros con 165 adiciones y 350 borrados
  1. +1
    -1
      btpd/Makefile.am
  2. +32
    -2
      btpd/btpd.c
  3. +1
    -1
      btpd/btpd.h
  4. +14
    -18
      btpd/download.c
  5. +0
    -1
      btpd/download.h
  6. +8
    -87
      btpd/download_subr.c
  7. +4
    -1
      btpd/main.c
  8. +1
    -1
      btpd/net.c
  9. +5
    -4
      btpd/net_buf.c
  10. +12
    -11
      btpd/peer.c
  11. +56
    -190
      btpd/torrent.c
  12. +22
    -19
      btpd/torrent.h
  13. +5
    -10
      btpd/tracker_req.c
  14. +4
    -4
      btpd/upload.c

+ 1
- 1
btpd/Makefile.am Ver fichero

@@ -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\


+ 32
- 2
btpd/btpd.c Ver fichero

@@ -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);


+ 1
- 1
btpd/btpd.h Ver fichero

@@ -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)


+ 14
- 18
btpd/download.c Ver fichero

@@ -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);
}


+ 0
- 1
btpd/download.h Ver fichero

@@ -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);


+ 8
- 87
btpd/download_subr.c Ver fichero

@@ -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) {
@@ -195,79 +194,10 @@ dl_find_piece(struct torrent *tp, uint32_t index)
return pc;
}

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);
}

/*


+ 4
- 1
btpd/main.c Ver fichero

@@ -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;


+ 1
- 1
btpd/net.c Ver fichero

@@ -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);


+ 5
- 4
btpd/net_buf.c Ver fichero

@@ -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;
}



+ 12
- 11
btpd/peer.c Ver fichero

@@ -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;
}
}
}
}


+ 56
- 190
btpd/torrent.c Ver fichero

@@ -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();
}
}

+ 22
- 19
btpd/torrent.h Ver fichero

@@ -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

+ 5
- 10
btpd/tracker_req.c Ver fichero

@@ -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"


+ 4
- 4
btpd/upload.c Ver fichero

@@ -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++;


Cargando…
Cancelar
Guardar