libeech

BitTorrent library
git clone git://z3bra.org/libeech.git
Log | Files | Refs | README | LICENSE

commit 733ceaa38e147aec1a34dcb7fb3d4135a3b452a8
parent ebf503552dc21e5192be8f126dc9f65ae8f2529c
Author: z3bra <contactatz3bradotorg>
Date:   Fri Nov  3 15:59:45 +0100

Add functions to manage peers

Diffstat:
libeech.c | 118++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
libeech.h | 6++++++
2 files changed, 123 insertions(+), 1 deletion(-)
diff --git a/libeech.c b/libeech.c @@ -1,11 +1,16 @@ /* See LICENSE file for copyright and license details. */ +#include <fcntl.h> #include <limits.h> +#include <netdb.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> +#include <sys/socket.h> +#include <netinet/in.h> + #include "be.h" #include "sha1.h" #include "util.h" @@ -17,6 +22,13 @@ static long torrentsize(struct torrent *); static long torrentfiles(struct torrent *); static int chktorrent(struct be *); +/* manage a list of peers */ +static int tcpconnect(char *, int); +static struct peer * addpeer(struct peer *, char *, int); +static struct peer * getpeer(struct peer *, char *, int); +static struct peer * delpeer(struct peer *, struct peer *); +static int peercnt(struct peer *); + static char * peerid() { @@ -76,7 +88,7 @@ torrentfiles(struct torrent *t) t->files = malloc(sizeof(*t->files) * n); if (!t->files) return -1; - + for (i = 0; !belistnext(&file) && !belistover(&file); i++) { /* save file length */ t->files[i].sz = bekint(&file, "length", 6); @@ -146,6 +158,92 @@ chktorrent(struct be *b) return 0; } +static int +tcpconnect(char *host, int port) +{ + int fd = -1; + int flags = 0; + struct hostent *he; + struct sockaddr_in in; + + if (!(he = gethostbyname(host))) + return -1; + + memset(&in, 0, sizeof(in)); + memcpy(&in.sin_addr, he->h_addr_list[0], he->h_length); + in.sin_family = AF_INET; + in.sin_port = htons(port); + + fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (fd < 0) + return -1; + + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + return -1; + + if (fcntl(fd, F_SETFL, flags|O_NONBLOCK) < 0) + return -1; + + if (connect(fd, (struct sockaddr *)&in, sizeof(in)) < 0) + return -1; + + return fd; +} + +static struct peer * +addpeer(struct peer *pl, char *host, int port) +{ + struct peer *p; + + p = malloc(sizeof(*p)); + if (!p) + return NULL; + + p->fd = -1; + p->state = 0; + p->next = pl; + p->port = port; + memcpy(p->host, host, HOST_NAME_MAX); + + return p; +} + +static struct peer * +getpeer(struct peer *pl, char *host, int port) +{ + struct peer *p; + + for (p = pl; p; p = p->next) { + if (p->port == port && !strncmp(p->host, host, HOST_NAME_MAX)) + return p; + } + return NULL; +} + +static struct peer * +delpeer(struct peer *pl, struct peer *p) +{ + struct peer *tmp; + + if (p == pl) { + pl = pl->next; + } else { + for (tmp = pl; tmp->next == p; tmp = tmp->next); + tmp->next = p->next; + } + + free(p); + return pl; +} + +static int +peercnt(struct peer *pl) +{ + return (pl ? 1 : 0) + peercnt(pl->next); +} + + int glch_loadtorrent(struct torrent *t, char *b, size_t s) { @@ -173,6 +271,24 @@ glch_loadtorrent(struct torrent *t, char *b, size_t s) t->dl = 0; t->sz = torrentsize(t); t->nfile = torrentfiles(t); + t->peers = NULL; + + return 0; +} + +int +glch_addpeer(struct torrent *t, char *host, int port) +{ + struct peer *p; + + /* ignore request if peer already exists */ + if (getpeer(t->peers, host, port)) + return 0; + + p = addpeer(t->peers, host, port); + if (!p) + return -1; + t->peers = p; return 0; } diff --git a/libeech.h b/libeech.h @@ -20,6 +20,10 @@ enum { struct peer { int fd; int state; + int port; + char host[HOST_NAME_MAX]; + int (*connect)(char *, int); + struct peer *next; }; struct file { @@ -33,6 +37,7 @@ struct torrent { char tr[PATH_MAX]; struct be be; struct be info; + struct peer *peers; struct file *files; long nfile; long sz; @@ -41,3 +46,4 @@ struct torrent { }; int glch_loadtorrent(struct torrent *, char *, size_t); +int glch_addpeer(struct torrent *, char *, int);