瀏覽代碼

All files:

Each piece must have at least one byte for their block bit array,
  or they will collide causing great confusion in btpd. The calculation
  was done wrong so this could happen for small torrents (blocks / piece < 8).

policy_subr.c:
  * Add test for correctness.
  * Add missing call to cm_on_piece_full in cm_new_piece.
master
Richard Nyberg 19 年之前
父節點
當前提交
17a1f68906
共有 3 個檔案被更改,包括 24 行新增25 行删除
  1. +21
    -21
      btpd/policy_subr.c
  2. +1
    -1
      btpd/torrent.c
  3. +2
    -3
      cli/btcli.c

+ 21
- 21
btpd/policy_subr.c 查看文件

@@ -48,7 +48,7 @@ piece_alloc(struct torrent *tp, uint32_t index)
pc->down_field = (uint8_t *)(pc + 1);
pc->have_field =
tp->block_field +
(size_t)ceil(index * tp->meta.piece_length / (double)(1 << 17));
index * (size_t)ceil(tp->meta.piece_length / (double)(1 << 17));
pc->nblocks = nblocks;
pc->index = index;

@@ -254,6 +254,24 @@ cm_choose_rarest(struct peer *p, uint32_t *res)
return 0;
}

/*
* Called from either cm_piece_assign_requests or cm_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.
*/
static void
cm_on_piece_full(struct piece *pc)
{
struct peer *p;
BTPDQ_FOREACH(p, &pc->tp->peers, cm_entry) {
if (peer_has(p, pc->index))
peer_unwant(p, pc->index);
}
if (cm_should_enter_endgame(pc->tp))
cm_enter_endgame(pc->tp);
}

/*
* Allocate the piece indicated by the index for download.
* There's a small possibility that a piece is fully downloaded
@@ -269,6 +287,7 @@ cm_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) {
cm_on_piece_full(pc);
cm_on_piece(pc);
if (cm_should_enter_endgame(tp))
cm_enter_endgame(tp);
@@ -277,25 +296,6 @@ cm_new_piece(struct torrent *tp, uint32_t index)
return pc;
}

/*
* Called from either cm_piece_assign_requests or cm_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.
*/
static void
cm_on_piece_full(struct piece *pc)
{
struct peer *p;
BTPDQ_FOREACH(p, &pc->tp->peers, cm_entry) {
if (peer_has(p, pc->index))
peer_unwant(p, pc->index);
}
if (cm_should_enter_endgame(pc->tp))
cm_enter_endgame(pc->tp);
}


/*
* Called when a previously full piece loses a peer.
* This is needed because we have decreased the wanted
@@ -360,7 +360,7 @@ cm_piece_assign_requests(struct piece *pc, struct peer *p)
unsigned
cm_assign_requests(struct peer *p)
{
assert(!p->tp->endgame);
assert(!p->tp->endgame && !peer_laden(p));
struct piece *pc;
struct torrent *tp = p->tp;
unsigned count = 0;


+ 1
- 1
btpd/torrent.c 查看文件

@@ -94,7 +94,7 @@ torrent_load2(const char *file, struct metainfo *mi)

memsiz =
ceil(mi->npieces / 8.0) +
ceil(mi->npieces * mi->piece_length / (double)(1 << 17));
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);


+ 2
- 3
cli/btcli.c 查看文件

@@ -138,9 +138,8 @@ gen_ifile(char *path)
if ((errno = vopen(&fd, O_WRONLY|O_CREAT, "%s.i", path)) != 0)
err(1, "opening %s.i", path);

if (ftruncate(fd,
field_len +
(off_t)ceil(mi->npieces * mi->piece_length / (double)(1<<17))) < 0)
if (ftruncate(fd, field_len + mi->npieces *
(off_t)ceil(mi->piece_length / (double)(1 << 17))) < 0)
err(1, "ftruncate: %s", path);

if (write(fd, cb.piece_field, field_len) != field_len)


Loading…
取消
儲存