commit 691c21ea9dc4912bbe7b8c4450d2d11318464afd
parent b7d2d815cccbbfccb7bd9ad22b5a49cc1c1bcc8c
Author: sin <sin@2f30.org>
Date: Wed, 23 Dec 2015 19:18:21 +0000
messy but prints peers
Diffstat:
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);