tAdd functions to manage peers - libeech - bittorrent library
 (HTM) git clone git://z3bra.org/libeech.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 733ceaa38e147aec1a34dcb7fb3d4135a3b452a8
 (DIR) parent ebf503552dc21e5192be8f126dc9f65ae8f2529c
 (HTM) Author: z3bra <contactatz3bradotorg>
       Date:   Fri,  3 Nov 2017 15:59:45 +0100
       
       Add functions to manage peers
       
       Diffstat:
         M libeech.c                           |     118 ++++++++++++++++++++++++++++++-
         M libeech.h                           |       6 ++++++
       
       2 files changed, 123 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/libeech.c b/libeech.c
       t@@ -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"
       t@@ -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()
        {
       t@@ -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);
       t@@ -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)
        {
       t@@ -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;
        }
 (DIR) diff --git a/libeech.h b/libeech.h
       t@@ -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 {
       t@@ -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;
       t@@ -41,3 +46,4 @@ struct torrent {
        };
        
        int glch_loadtorrent(struct torrent *, char *, size_t);
       +int glch_addpeer(struct torrent *, char *, int);