commit 8aa145f7ac541439c9fc0e3fed3e6863ddbd1af5
parent 5aea366f22b0facb7cc3dd2d57906c74cc78b907
Author: sin <sin@2f30.org>
Date: Sat, 26 Dec 2015 17:05:15 +0000
add peer.c
Diffstat:
M | Makefile | | | 1 | + |
A | peer.c | | | 71 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | storrent.h | | | 9 | ++++++++- |
M | tracker.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)
{