diff --git a/btpd/net.c b/btpd/net.c index 1c22111..ecd76e0 100644 --- a/btpd/net.c +++ b/btpd/net.c @@ -58,6 +58,18 @@ net_write_cb(int sd, short type, void *arg) } } +void +net_write32(void *buf, uint32_t num) +{ + *(uint32_t *)buf = htonl(num); +} + +uint32_t +net_read32(void *buf) +{ + return ntohl(*(uint32_t *)buf); +} + static void kill_buf_no(char *buf, size_t len) { @@ -93,7 +105,7 @@ struct net_buf * nb_create_alloc(short type, size_t len) { struct net_buf *nb = btpd_calloc(1, sizeof(*nb) + len); - nb->info.type = type; + nb->type = type; nb->buf = (char *)(nb + 1); nb->len = len; nb->kill_buf = kill_buf_no; @@ -105,13 +117,54 @@ nb_create_set(short type, char *buf, size_t len, void (*kill_buf)(char *, size_t)) { struct net_buf *nb = btpd_calloc(1, sizeof(*nb)); - nb->info.type = type; + nb->type = type; nb->buf = buf; nb->len = len; nb->kill_buf = kill_buf; return nb; } +uint32_t +nb_get_index(struct net_buf *nb) +{ + switch (nb->type) { + case NB_CANCEL: + case NB_HAVE: + case NB_PIECE: + case NB_REQUEST: + return net_read32(nb->buf + 5); + default: + abort(); + } +} + +uint32_t +nb_get_begin(struct net_buf *nb) +{ + switch (nb->type) { + case NB_CANCEL: + case NB_PIECE: + case NB_REQUEST: + return net_read32(nb->buf + 9); + default: + abort(); + } +} + +uint32_t +nb_get_length(struct net_buf *nb) +{ + switch (nb->type) { + case NB_CANCEL: + case NB_REQUEST: + return net_read32(nb->buf + 13); + case NB_PIECE: + return net_read32(nb->buf) - 9; + default: + abort(); + } +} + void kill_shake(struct input_reader *reader) { @@ -173,7 +226,7 @@ net_write(struct peer *p, unsigned long wmax) while (bcount > 0) { unsigned long bufdelta = nl->nb->len - p->outq_off; if (bcount >= bufdelta) { - if (nl->nb->info.type == NB_TORRENTDATA) { + if (nl->nb->type == NB_TORRENTDATA) { p->tp->uploaded += bufdelta; p->rate_from_me[btpd.seconds % RATEHISTORY] += bufdelta; } @@ -184,7 +237,7 @@ net_write(struct peer *p, unsigned long wmax) p->outq_off = 0; nl = BTPDQ_FIRST(&p->outq); } else { - if (nl->nb->info.type == NB_TORRENTDATA) { + if (nl->nb->type == NB_TORRENTDATA) { p->tp->uploaded += bcount; p->rate_from_me[btpd.seconds % RATEHISTORY] += bcount; } @@ -243,18 +296,6 @@ net_unsend(struct peer *p, struct nb_link *nl) return 0; } -void -net_write32(void *buf, uint32_t num) -{ - *(uint32_t *)buf = htonl(num); -} - -uint32_t -net_read32(void *buf) -{ - return ntohl(*(uint32_t *)buf); -} - void net_send_piece(struct peer *p, uint32_t index, uint32_t begin, char *block, size_t blen) @@ -271,9 +312,6 @@ net_send_piece(struct peer *p, uint32_t index, uint32_t begin, net_send(p, head); piece = nb_create_set(NB_TORRENTDATA, block, blen, kill_buf_free); - piece->info.index = index; - piece->info.begin = begin; - piece->info.length = blen; net_send(p, piece); } @@ -286,9 +324,6 @@ net_send_request(struct peer *p, struct piece_req *req) net_write32(out->buf + 5, req->index); net_write32(out->buf + 9, req->begin); net_write32(out->buf + 13, req->length); - out->info.index = req->index; - out->info.begin = req->begin; - out->info.length = req->length; net_send(p, out); } @@ -301,9 +336,6 @@ net_send_cancel(struct peer *p, struct piece_req *req) net_write32(out->buf + 5, req->index); net_write32(out->buf + 9, req->begin); net_write32(out->buf + 13, req->length); - out->info.index = req->index; - out->info.begin = req->begin; - out->info.length = req->length; net_send(p, out); } @@ -314,7 +346,6 @@ net_send_have(struct peer *p, uint32_t index) net_write32(out->buf, 5); out->buf[4] = MSG_HAVE; net_write32(out->buf + 5, index); - out->info.index = index; net_send(p, out); } diff --git a/btpd/net.h b/btpd/net.h index 048a19b..9fe7b30 100644 --- a/btpd/net.h +++ b/btpd/net.h @@ -26,13 +26,8 @@ #define NB_SHAKE 13 struct net_buf { + short type; unsigned refs; - - struct { - short type; - uint32_t index, begin, length; - } info; - char *buf; size_t len; void (*kill_buf)(char *, size_t); @@ -50,6 +45,9 @@ struct net_buf *nb_create_set(short type, char *buf, size_t len, void (*kill_buf)(char *, size_t)); int nb_drop(struct net_buf *nb); void nb_hold(struct net_buf *nb); +uint32_t nb_get_index(struct net_buf *nb); +uint32_t nb_get_begin(struct net_buf *nb); +uint32_t nb_get_length(struct net_buf *nb); struct peer; diff --git a/btpd/peer.c b/btpd/peer.c index a8058a6..7126bdc 100644 --- a/btpd/peer.c +++ b/btpd/peer.c @@ -62,6 +62,8 @@ peer_kill(struct peer *p) void peer_request(struct peer *p, uint32_t index, uint32_t begin, uint32_t len) { + if (p->tp->endgame == 0) + assert(p->nreqs_out < MAXPIPEDREQUESTS); p->nreqs_out++; struct piece_req *req = btpd_calloc(1, sizeof(*req)); req->index = index; @@ -76,12 +78,9 @@ peer_cancel(struct peer *p, uint32_t index, uint32_t begin, uint32_t len) { struct piece_req *req; again: - req = BTPDQ_FIRST(&p->my_reqs); - while (req != NULL && - !(index == req->index && - begin == req->begin && - len == req->length)) - req = BTPDQ_NEXT(req, entry); + BTPDQ_FOREACH(req, &p->my_reqs, entry) + if (index == req->index && begin == req->begin && len == req->length) + break; if (req != NULL) { net_send_cancel(p, req); BTPDQ_REMOVE(&p->my_reqs, req, entry); @@ -110,7 +109,7 @@ peer_choke(struct peer *p) struct nb_link *nl = BTPDQ_FIRST(&p->outq); while (nl != NULL) { struct nb_link *next = BTPDQ_NEXT(nl, entry); - if (nl->nb->info.type == NB_PIECE) { + if (nl->nb->type == NB_PIECE) { struct nb_link *data = next; next = BTPDQ_NEXT(next, entry); if (net_unsend(p, nl)) @@ -306,10 +305,10 @@ peer_on_cancel(struct peer *p, uint32_t index, uint32_t begin, { struct nb_link *nl; BTPDQ_FOREACH(nl, &p->outq, entry) - if (nl->nb->info.type == NB_PIECE - && nl->nb->info.index == index - && nl->nb->info.begin == begin - && nl->nb->info.length == length) { + if (nl->nb->type == NB_PIECE + && nb_get_begin(nl->nb) == begin + && nb_get_index(nl->nb) == index + && nb_get_length(nl->nb) == length) { struct nb_link *data = BTPDQ_NEXT(nl, entry); if (net_unsend(p, nl)) net_unsend(p, data);