torrentd

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

commit 691c21ea9dc4912bbe7b8c4450d2d11318464afd
parent b7d2d815cccbbfccb7bd9ad22b5a49cc1c1bcc8c
Author: sin <sin@2f30.org>
Date:   Wed, 23 Dec 2015 19:18:21 +0000

messy but prints peers

Diffstat:
Mstorrent.c | 3+--
Mstorrent.h | 9++++++++-
Mtracker.c | 49++++++++++++++++++++++++++++++++++++++++++++-----
3 files changed, 53 insertions(+), 8 deletions(-)

diff --git a/storrent.c b/storrent.c @@ -15,7 +15,6 @@ usage(char *argv0) int main(int argc, char *argv[]) { - struct ben *peers; struct torrent *t; if (argc != 2) @@ -23,7 +22,7 @@ main(int argc, char *argv[]) if (!(t = loadtorrent(argv[1]))) exit(1); dumptorrent(t); - getpeers(t, &peers); + getpeers(t); unloadtorrent(t); exit(0); } diff --git a/storrent.h b/storrent.h @@ -20,6 +20,11 @@ struct announce { size_t len; }; +struct peer { + char hostname[256]; + char port[6]; +}; + struct torrent { char *buf; size_t buflen; @@ -36,6 +41,8 @@ struct torrent { long long piecelen; long long npieces; uint32_t *piecebm; + struct peer *peers; + size_t npeers; }; /* ben.c */ @@ -58,7 +65,7 @@ int piecehash(struct torrent *, long long, uint8_t *); char *peerid(void); /* tracker.c */ -int getpeers(struct torrent *, struct ben **); +int getpeers(struct torrent *); /* util.c */ void *emalloc(size_t); diff --git a/tracker.c b/tracker.c @@ -1,4 +1,10 @@ /* 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> @@ -7,14 +13,16 @@ #include "storrent.h" int -getpeers(struct torrent *t, struct ben **reply) +getpeers(struct torrent *t) { + struct sockaddr_in sa; + struct ben *reply, *peers; + struct peer *peer; char *url, *proto, *host, *port, *path; char *infohash, *id; char buf[8192], *p; int r, s; - *reply = NULL; url = parseurl(t->announcers[0].urls[0], &proto, &host, &port, &path); infohash = urlencode((char *)t->infohash, 20); id = urlencode(peerid(), 20); @@ -25,7 +33,7 @@ getpeers(struct torrent *t, struct ben **reply) r = snprintf(buf, sizeof(buf), "GET /%s?info_hash=%s&peer_id=%s&port=6881&uploaded=0&" - "downloaded=0&left=%zu&event=started HTTP/1.1\r\n\r\n", + "downloaded=0&left=%zu&compact=1&event=started HTTP/1.1\r\n\r\n", path, infohash, id, t->totallen); if (r < 0 || (size_t)r >= sizeof(buf)) goto fail; @@ -47,9 +55,40 @@ getpeers(struct torrent *t, struct ben **reply) p = buf; } - if (!bdecode(p, p + r, reply)) + if (!bdecode(p, p + r, &reply)) + goto fail; + peers = dlookstr(reply, "peers"); + if (!peers) { + warnx("no peers field in tracker reply"); + bfree(reply); goto fail; - bprint(*reply, 0); + } + if (peers->type != 's') { + warnx("expected compact reply"); + bfree(reply); + goto fail; + } + if (peers->len % 6) { + warnx("peers length needs to be a multiple of 6 bytes"); + bfree(reply); + goto fail; + } + + 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++; + } + + bfree(reply); free(id); free(infohash); free(url);