From 51b913eb2ff91adfe8cd5e417759a6057c5a8a21 Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Thu, 13 Nov 2008 16:17:55 +0000 Subject: XBitTorrent --- netio.c | 185 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 netio.c (limited to 'netio.c') diff --git a/netio.c b/netio.c new file mode 100644 index 0000000..6fc4d4b --- /dev/null +++ b/netio.c @@ -0,0 +1,185 @@ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "meta.h" +#include "files.h" +#include "peer.h" +#include "netio.h" + +LIST_HEAD(btclist, btchunk) chead; +LIST_HEAD(btrlist, btrequest) rhead; + +struct btrequest *allocrequest(struct btmeta *, struct btpeer *, int, off_t, off_t); +int freerequest(struct btmeta *, struct btpeer *, int n, off_t, off_t); +struct btchunk *allocchunk(struct btmeta *, int); +int freechunk(struct btmeta *, int); + +/* DON'T FORGET: + +LIST_INIT(&chead); +LIST_INIT(&rhead); + + */ + +struct btrequest * +btallocrequest(struct btmeta *mp, struct btpeer *p, int n, off_t off, off_t len) +{ + struct btrequest *r; + + r = malloc(sizeof(struct btrequest)); + assert(r); + + r->peer = p; + r->offset = off; + r->length = len; + r->chunk = allocchunk(mp, n); + r->transmitted = 0; + + LIST_INSERT_HEAD(&rhead, r, link); + + return r; +} + +int +btfreerequest(struct btmeta *mp, struct btpeer *p, int n, off_t off, off_t len) +{ + struct btrequest *r, *nxt; + + for (r = LIST_FIRST(&rhead); r != LIST_END(&rhead); r = nxt) { + nxt = LIST_NEXT(r, link); + if (r->peer == p && r->offset == off && r->length == len) { + if (freechunk(mp, r->chunk->piece) == -1) + return -1; + LIST_REMOVE(r, link); + free(r); + return 0; + } + } + return -1; +} + +int +btwriterequest(struct btpeer *p, int n, off_t off, off_t len) +{ + struct btrequest *r, *nxt; + + for (r = LIST_FIRST(&rhead); r != LIST_END(&rhead); r = nxt) { + nxt = LIST_NEXT(r, link); + if (r->peer == p && r->offset == off && r->length == len) { + memcpy(r->chunk->data + r->offset, p->msgbuf, p->buflen); + return 0; + } + } + return -1; +} + +struct btchunk * +allocchunk(struct btmeta *mp, int n) +{ + struct btchunk *p; + + /* look if we have already that chunk */ + LIST_FOREACH(p, &chead, link) { + if (p->piece == n) { + ++p->ref; + return p; + } + } + + /* not found, allocate a new one */ + p = malloc(sizeof(struct btchunk)); + assert(p); + p->ref = 1; + p->piece = n; + p->sha1 = mp->pieces[n]; + p->len = btsizeofpiece(mp, n); + p->data = calloc(p->len, sizeof(char)); + assert(p->data); + if (btisset(mp->bitfield, n)) + btread(mp, p->data, p->len, n); + + return p; +} + +int +freechunk(struct btmeta *mp, int n) +{ + struct btchunk *p, *nxt; + + for (p = LIST_FIRST(&chead); p != LIST_END(&chead); p = nxt) { + nxt = LIST_NEXT(p, link); + if (p->piece == n) { + /* do we have it already? */ + if (btisset(mp->bitfield, n)) + return 1; + + /* check and write */ + if (!btcheck(p->sha1, p->data, p->len) || !btwrite(mp, p->data, p->len, n)) + return -1; + btsetbit(mp->bitfield, n); + + if (--p->ref <= 0) { + /* nobody refers anymore to this piece */ + LIST_REMOVE(p, link); + free(p->data); + free(p); + } + + /* announce all that we have that piece */ + return 0; + } + } + + /* nothing found */ + return -1; +} + + + + +#if 0 + +/* put message on queue */ +/* needed vars: + data, length, + send/recv (*fp)() + socket + */ + +void +btputqueue(struct btqueue *head, struct btpeer *p, ssize_t (*fp)(int, void *, size_t, int)) +{ + struct btqentry *q; + + q = malloc(sizeof(struct btqentry)); + assert(q); + + q->data = p->data + p->offset; + q->length = p->length; + q->doit = fp; + q->sockd = p->sockd; + + SIMPLEQ_INSERT_TAIL(head, q, link); +} + +int +nonblock(int s) +{ + int flags; + + flags = fcntl(s, F_GETFL); + if (flags < 0 || fcntl(s, F_SETFL, flags|O_NONBLOCK) < 0) + return -1; + + return s; +} + +#endif -- cgit v1.2.3