torrentd

simple torrent daemon
git clone git@git.2f30.org/torrentd.git
Log | Files | Refs | LICENSE

commit 8aa145f7ac541439c9fc0e3fed3e6863ddbd1af5
parent 5aea366f22b0facb7cc3dd2d57906c74cc78b907
Author: sin <sin@2f30.org>
Date:   Sat, 26 Dec 2015 17:05:15 +0000

add peer.c

Diffstat:
MMakefile | 1+
Apeer.c | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mstorrent.h | 9++++++++-
Mtracker.c | 58----------------------------------------------------------
4 files changed, 80 insertions(+), 59 deletions(-)

diff --git a/Makefile b/Makefile @@ -13,6 +13,7 @@ LDFLAGS = $(LIBS) OBJ =\ ben.o\ + peer.o\ sha1.o\ sock.o\ storrent.o\ diff --git a/peer.c b/peer.c @@ -0,0 +1,71 @@ +/* See LICENSE file for copyright and license details. */ +#include <sys/socket.h> + +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <err.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "storrent.h" + +int +parsepeers(struct torrent *t, struct buf *b) +{ + struct sockaddr_in sa; + struct ben *reply, *peers; + struct peer *peer; + char *p, *errstr; + + if (!bdecode(b->p, b->p + b->n, &reply)) + return -1; + + if (dlookstr(reply, "failure reason")) { + errstr = bstr2str(dlookstr(reply, "failure reason")); + warnx("tracker failure: %s", errstr); + bfree(reply); + free(errstr); + return -1; + } + + if (!(peers = dlookstr(reply, "peers"))) { + warnx("no peers field in tracker reply"); + bfree(reply); + return -1; + } + + if (peers->type != 's') { + warnx("expected compact reply"); + bfree(reply); + return -1; + } + + if (peers->len % 6) { + warnx("peers length needs to be a multiple of 6 bytes"); + bfree(reply); + return -1; + } + + for (p = peers->s; p < &peers->s[peers->len]; p += 6) { + t->peers = realloc(t->peers, (t->npeers + 1) * sizeof(*t->peers)); + if (!t->peers) + err(1, "realloc"); + peer = &t->peers[t->npeers]; + memset(peer, 0, sizeof(*peer)); + memcpy(&sa.sin_addr, p, 4); + inet_ntop(AF_INET, &sa.sin_addr, peer->hostname, + sizeof(peer->hostname)); + snprintf(peer->port, sizeof(peer->port), "%d", + (int)ntohs(*(short *)&p[4])); + printf("%s:%s\n", peer->hostname, peer->port); + peer->amchoking = 1; + peer->peerchoking = 1; + t->npeers++; + } + + free(reply); + return 0; +} diff --git a/storrent.h b/storrent.h @@ -34,8 +34,12 @@ struct announce { }; struct peer { - char hostname[256]; + char hostname[16]; /* ipv4 only */ char port[6]; + int amchoking; + int aminterested; + int peerchoking; + int peerinterested; }; struct torrent { @@ -69,6 +73,9 @@ struct ben *dlookstr(struct ben *, char *); void bfree(struct ben *); void bprint(struct ben *, int); +/* peer.c */ +int parsepeers(struct torrent *, struct buf *); + /* sock.c */ int dial(char *, char *); diff --git a/tracker.c b/tracker.c @@ -1,7 +1,4 @@ /* See LICENSE file for copyright and license details. */ -#include <arpa/inet.h> -#include <netinet/in.h> - #include <err.h> #include <stdint.h> #include <stdio.h> @@ -18,61 +15,6 @@ writefn(void *ptr, size_t size, size_t nmemb, struct buf *b) return fillbuf(b, ptr, size * nmemb); } -static int -parsepeers(struct torrent *t, struct buf *b) -{ - struct sockaddr_in sa; - struct ben *reply, *peers; - struct peer *peer; - char *p, *errstr; - - if (!bdecode(b->p, b->p + b->n, &reply)) - return -1; - - if (dlookstr(reply, "failure reason")) { - errstr = bstr2str(dlookstr(reply, "failure reason")); - warnx("tracker failure: %s", errstr); - bfree(reply); - free(errstr); - return -1; - } - - if (!(peers = dlookstr(reply, "peers"))) { - warnx("no peers field in tracker reply"); - bfree(reply); - return -1; - } - - if (peers->type != 's') { - warnx("expected compact reply"); - bfree(reply); - return -1; - } - - if (peers->len % 6) { - warnx("peers length needs to be a multiple of 6 bytes"); - bfree(reply); - return -1; - } - - for (p = peers->s; p < &peers->s[peers->len]; p += 6) { - t->peers = realloc(t->peers, (t->npeers + 1) * sizeof(*t->peers)); - if (!t->peers) - err(1, "realloc"); - peer = &t->peers[t->npeers]; - memcpy(&sa.sin_addr, p, 4); - inet_ntop(AF_INET, &sa.sin_addr, peer->hostname, - sizeof(peer->hostname)); - snprintf(peer->port, sizeof(peer->port), "%d", - (int)ntohs(*(short *)&p[4])); - printf("%s:%s\n", peer->hostname, peer->port); - t->npeers++; - } - - free(reply); - return 0; -} - int trackerget(struct torrent *t, int event) {