Pārlūkot izejas kodu

* Better interface between the net and peer code.

The net code now calls the peer code when it has read a full message.
  This has mostly involved moving code from net.c to peer.c.

* Added torrent_piece_size helper function.
master
Richard Nyberg pirms 19 gadiem
vecāks
revīzija
474c7b5b3a
6 mainītis faili ar 162 papildinājumiem un 96 dzēšanām
  1. +24
    -89
      btpd/net.c
  2. +2
    -0
      btpd/net.h
  3. +107
    -4
      btpd/peer.c
  4. +15
    -2
      btpd/peer.h
  5. +12
    -1
      btpd/torrent.c
  6. +2
    -0
      btpd/torrent.h

+ 24
- 89
btpd/net.c Parādīt failu

@@ -476,12 +476,7 @@ read_bitfield(struct peer *p, unsigned long rmax)

rd->iob.buf_off += nread;
if (rd->iob.buf_off == rd->iob.buf_len) {
bcopy(rd->iob.buf, p->piece_field, rd->iob.buf_len);
for (unsigned i = 0; i < p->tp->meta.npieces; i++)
if (has_bit(p->piece_field, i)) {
p->npieces++;
cm_on_piece_ann(p, i);
}
peer_on_bitfield(p, rd->iob.buf);
free(rd);
net_generic_reader(p);
} else
@@ -513,16 +508,7 @@ read_piece(struct peer *p, unsigned long rmax)
p->rate_to_me[btpd.seconds % RATEHISTORY] += nread;
p->tp->downloaded += nread;
if (rd->iob.buf_off == rd->iob.buf_len) {
struct piece_req *req = BTPDQ_FIRST(&p->my_reqs);
if (req != NULL &&
req->index == rd->index &&
req->begin == rd->begin &&
req->length == rd->iob.buf_len) {
//
off_t cbegin = rd->index * p->tp->meta.piece_length + rd->begin;
torrent_put_bytes(p->tp, rd->iob.buf, cbegin, rd->iob.buf_len);
cm_on_block(p);
}
peer_on_piece(p, rd->index, rd->begin, rd->iob.buf_len, rd->iob.buf);
free(rd);
net_generic_reader(p);
} else
@@ -578,54 +564,33 @@ net_generic_read(struct peer *p, unsigned long rmax)
btpd_log(BTPD_L_MSG, "choke.\n");
if (msg_len != 1)
goto bad_data;
if ((p->flags & (PF_P_CHOKE|PF_I_WANT)) == PF_I_WANT) {
p->flags |= PF_P_CHOKE;
cm_on_undownload(p);
} else
p->flags |= PF_P_CHOKE;
peer_on_choke(p);
break;
case MSG_UNCHOKE:
btpd_log(BTPD_L_MSG, "unchoke.\n");
if (msg_len != 1)
goto bad_data;
if ((p->flags & (PF_P_CHOKE|PF_I_WANT))
== (PF_P_CHOKE|PF_I_WANT)) {
p->flags &= ~PF_P_CHOKE;
cm_on_download(p);
} else
p->flags &= ~PF_P_CHOKE;
peer_on_unchoke(p);
break;
case MSG_INTEREST:
btpd_log(BTPD_L_MSG, "interested.\n");
if (msg_len != 1)
goto bad_data;
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == 0) {
p->flags |= PF_P_WANT;
cm_on_upload(p);
} else
p->flags |= PF_P_WANT;
peer_on_interest(p);
break;
case MSG_UNINTEREST:
btpd_log(BTPD_L_MSG, "uninterested.\n");
if (msg_len != 1)
goto bad_data;
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT) {
p->flags &= ~PF_P_WANT;
cm_on_unupload(p);
} else
p->flags &= ~PF_P_WANT;
peer_on_uninterest(p);
break;
case MSG_HAVE:
btpd_log(BTPD_L_MSG, "have.\n");
if (msg_len != 5)
goto bad_data;
else if (len - off >= msg_len + 4) {
unsigned long piece = net_read32(buf + off + 5);
if (!has_bit(p->piece_field, piece)) {
set_bit(p->piece_field, piece);
p->npieces++;
cm_on_piece_ann(p, piece);
}
uint32_t index = net_read32(buf + off + 5);
peer_on_have(p, index);
} else
got_part = 1;
break;
@@ -635,14 +600,9 @@ net_generic_read(struct peer *p, unsigned long rmax)
goto bad_data;
else if (p->npieces != 0)
goto bad_data;
else if (len - off >= msg_len + 4) {
bcopy(buf + off + 5, p->piece_field, msg_len - 1);
for (unsigned i = 0; i < p->tp->meta.npieces; i++)
if (has_bit(p->piece_field, i)) {
p->npieces++;
cm_on_piece_ann(p, i);
}
} else {
else if (len - off >= msg_len + 4)
peer_on_bitfield(p, buf + off + 5);
else {
struct bitfield_reader *rp;
size_t mem = sizeof(*rp) + msg_len - 1;
p->reader->kill(p->reader);
@@ -666,23 +626,18 @@ net_generic_read(struct peer *p, unsigned long rmax)
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) != PF_P_WANT)
break;
uint32_t index, begin, length;
off_t cbegin;
char *content;
index = net_read32(buf + off + 5);
begin = net_read32(buf + off + 9);
length = net_read32(buf + off + 13);
if (length > (1 << 15))
goto bad_data;
if (index >= p->tp->meta.npieces
|| !has_bit(p->tp->piece_field, index))
if (index >= p->tp->meta.npieces)
goto bad_data;
if (begin + length > p->tp->meta.piece_length)
if (!has_bit(p->tp->piece_field, index))
goto bad_data;
cbegin = index * p->tp->meta.piece_length + begin;
if (cbegin + length > p->tp->meta.total_length)
if (begin + length > torrent_piece_size(p->tp, index))
goto bad_data;
content = torrent_get_bytes(p->tp, cbegin, length);
net_send_piece(p, index, begin, content, length);
peer_on_request(p, index, begin, length);
} else
got_part = 1;
break;
@@ -695,18 +650,9 @@ net_generic_read(struct peer *p, unsigned long rmax)
uint32_t begin = net_read32(buf + off + 9);
uint32_t length = msg_len - 9;
if (len - off >= msg_len + 4) {
off_t cbegin = index * p->tp->meta.piece_length + begin;
p->tp->downloaded += length;
p->rate_to_me[btpd.seconds % RATEHISTORY] += length;
struct piece_req *req = BTPDQ_FIRST(&p->my_reqs);
if (req != NULL &&
req->index == index &&
req->begin == begin &&
req->length == length) {
//
torrent_put_bytes(p->tp, buf + off + 13, cbegin, length);
cm_on_block(p);
}
peer_on_piece(p, index, begin, length, buf + off + 13);
} else {
struct piece_reader *rp;
size_t mem = sizeof(*rp) + length;
@@ -734,27 +680,16 @@ net_generic_read(struct peer *p, unsigned long rmax)
if (msg_len != 13)
goto bad_data;
else if (len - off >= msg_len + 4) {
struct piece_req *req;
uint32_t index, begin, length;
index = net_read32(buf + off + 5);
begin = net_read32(buf + off + 9);
length = net_read32(buf + off + 13);
uint32_t index = net_read32(buf + off + 5);
uint32_t begin = net_read32(buf + off + 9);
uint32_t length = net_read32(buf + off + 13);
if (index > p->tp->meta.npieces)
goto bad_data;
if (begin + length > torrent_piece_size(p->tp, index))
goto bad_data;
btpd_log(BTPD_L_MSG, "cancel: %u, %u, %u\n",
index, begin, length);

req = BTPDQ_FIRST(&p->p_reqs);
while (req != NULL) {
if (req->index == index &&
req->begin == begin &&
req->length == length) {
btpd_log(BTPD_L_MSG, "cancel matched.\n");
net_unsend_piece(p, req);
break;
}
req = BTPDQ_NEXT(req, entry);
}
peer_on_cancel(p, index, begin, length);
} else
got_part = 1;
break;


+ 2
- 0
btpd/net.h Parādīt failu

@@ -93,6 +93,8 @@ void net_send_choke(struct peer *p);

void net_send_have(struct peer *p, uint32_t index);
void net_send_request(struct peer *p, struct piece_req *req);
void net_send_piece(struct peer *p, uint32_t index, uint32_t begin,
char *block, size_t blen);
void net_send_cancel(struct peer *p, struct piece_req *req);

void net_handshake(struct peer *p, int incoming);


+ 107
- 4
btpd/peer.c Parādīt failu

@@ -1,6 +1,8 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include <math.h>
#include <string.h>
#include <unistd.h>

@@ -166,10 +168,8 @@ peer_create_in(int sd)
}

void
peer_create_out(struct torrent *tp,
const uint8_t *id,
const char *ip,
int port)
peer_create_out(struct torrent *tp, const uint8_t *id,
const char *ip, int port)
{
int sd;
struct peer *p;
@@ -201,3 +201,106 @@ peer_create_out_compact(struct torrent *tp, const char *compact)
p->tp = tp;
net_handshake(p, 0);
}

void
peer_on_choke(struct peer *p)
{
if ((p->flags & (PF_P_CHOKE|PF_I_WANT)) == PF_I_WANT) {
p->flags |= PF_P_CHOKE;
cm_on_undownload(p);
} else
p->flags |= PF_P_CHOKE;
}

void
peer_on_unchoke(struct peer *p)
{
if ((p->flags & (PF_P_CHOKE|PF_I_WANT)) == (PF_P_CHOKE|PF_I_WANT)) {
p->flags &= ~PF_P_CHOKE;
cm_on_download(p);
} else
p->flags &= ~PF_P_CHOKE;
}

void
peer_on_interest(struct peer *p)
{
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == 0) {
p->flags |= PF_P_WANT;
cm_on_upload(p);
} else
p->flags |= PF_P_WANT;
}

void
peer_on_uninterest(struct peer *p)
{
if ((p->flags & (PF_P_WANT|PF_I_CHOKE)) == PF_P_WANT) {
p->flags &= ~PF_P_WANT;
cm_on_unupload(p);
} else
p->flags &= ~PF_P_WANT;
}

void
peer_on_have(struct peer *p, uint32_t index)
{
if (!has_bit(p->piece_field, index)) {
set_bit(p->piece_field, index);
p->npieces++;
cm_on_piece_ann(p, index);
}
}

void
peer_on_bitfield(struct peer *p, uint8_t *field)
{
assert(p->npieces == 0);
bcopy(field, p->piece_field, (size_t)ceil(p->tp->meta.npieces / 8.0));
for (uint32_t i = 0; i < p->tp->meta.npieces; i++) {
if (has_bit(p->piece_field, i)) {
p->npieces++;
cm_on_piece_ann(p, i);
}
}
}

void
peer_on_piece(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length, const char *data)
{
off_t cbegin = index * p->tp->meta.piece_length + begin;
struct piece_req *req = BTPDQ_FIRST(&p->my_reqs);
if (req != NULL &&
req->index == index &&
req->begin == begin &&
req->length == length) {
torrent_put_bytes(p->tp, data, cbegin, length);
cm_on_block(p);
}
}

void
peer_on_request(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length)
{
off_t cbegin = index * p->tp->meta.piece_length + begin;
char * content = torrent_get_bytes(p->tp, cbegin, length);
net_send_piece(p, index, begin, content, length);
}

void
peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length)
{
struct piece_req *req = BTPDQ_FIRST(&p->p_reqs);
while (req != NULL) {
if (req->index == index
&& req->begin == begin && req->length == length) {
btpd_log(BTPD_L_MSG, "cancel matched.\n");
net_unsend_piece(p, req);
break;
}
req = BTPDQ_NEXT(req, entry);
}
}

+ 15
- 2
btpd/peer.h Parādīt failu

@@ -48,7 +48,7 @@ void peer_choke(struct peer *p);
void peer_unwant(struct peer *p, uint32_t index);
void peer_want(struct peer *p, uint32_t index);
void peer_request(struct peer *p, uint32_t index,
uint32_t begin, uint32_t len);
uint32_t begin, uint32_t len);
void peer_cancel(struct peer *p, uint32_t index, uint32_t begin, uint32_t len);

void peer_have(struct peer *p, uint32_t index);
@@ -57,8 +57,21 @@ unsigned long peer_get_rate(unsigned long *rates);

void peer_create_in(int sd);
void peer_create_out(struct torrent *tp, const uint8_t *id,
const char *ip, int port);
const char *ip, int port);
void peer_create_out_compact(struct torrent *tp, const char *compact);
void peer_kill(struct peer *p);

void peer_on_interest(struct peer *p);
void peer_on_uninterest(struct peer *p);
void peer_on_choke(struct peer *p);
void peer_on_unchoke(struct peer *p);
void peer_on_have(struct peer *p, uint32_t index);
void peer_on_bitfield(struct peer *p, uint8_t *field);
void peer_on_piece(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length, const char *data);
void peer_on_request(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length);
void peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin,
uint32_t length);

#endif

+ 12
- 1
btpd/torrent.c Parādīt failu

@@ -43,7 +43,7 @@ torrent_load3(const char *file, struct metainfo *mi, char *mem, size_t memsiz)
btpd_err("Out of memory.\n");

tp->piece_count = btpd_calloc(mi->npieces, sizeof(tp->piece_count[0]));
BTPDQ_INIT(&tp->peers);
BTPDQ_INIT(&tp->getlst);

@@ -251,3 +251,14 @@ torrent_get_by_hash(const uint8_t *hash)
tp = BTPDQ_NEXT(tp, entry);
return tp;
}

off_t
torrent_piece_size(struct torrent *tp, uint32_t index)
{
if (index < tp->meta.npieces - 1)
return tp->meta.piece_length;
else {
off_t allbutlast = tp->meta.piece_length * (tp->meta.npieces - 1);
return tp->meta.total_length - allbutlast;
}
}

+ 2
- 0
btpd/torrent.h Parādīt failu

@@ -64,4 +64,6 @@ int torrent_has_peer(struct torrent *tp, const uint8_t *id);

struct torrent *torrent_get_by_hash(const uint8_t *hash);

off_t torrent_piece_size(struct torrent *tp, uint32_t index);

#endif

Notiek ielāde…
Atcelt
Saglabāt