summaryrefslogtreecommitdiffstats
path: root/src/dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht.c')
-rw-r--r--src/dht.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/dht.c b/src/dht.c
index 8cfe1ca..bd310ee 100644
--- a/src/dht.c
+++ b/src/dht.c
@@ -12,6 +12,7 @@
#include <resolv.h>
#include <limits.h>
#include <assert.h>
+#include <sha1.h> // http://github.com/clibs/sha1 and in major distributions
#define ECB 1
#define AES128 1
#include <aes.c>
@@ -166,6 +167,7 @@ void bucket_free (struct bucket * b) {
*/
struct peer {
+ int socket; /**< tcp socket for bep-0009 */
struct sockaddr_in6 addr; /**< peer ip address and port */
struct peer * next;
};
@@ -209,8 +211,7 @@ void peer_print (FILE * s, const struct peer * p) {
enum interested {
announce = 1 << 0, /**< will announce myself on every work() call with no packet */
peers = 1 << 1, /**< will get peers on every work() call with no packet */
- info = 1 << 2, /**< download metadata into `dht->dl`/$hash.info */
- dl = 1 << 3 /**< download torrent content into `dht->dl`/$hash.blob TODO */
+ info = 1 << 2 /**< download metadata into `dht->dl`/$hash.info */
};
/**
@@ -221,7 +222,7 @@ struct torrent {
enum interested type; /**< is truthy only for manually added torrents */
unsigned char hash[20]; /**< infohash */
struct peer * peers;
- struct node * nodes; /**< closest K DHT nodes to this hash, used only for announce, peers, info and dl torrents */
+ struct node * nodes; /**< closest K DHT nodes to this hash, used only for announce, peers and info torrents */
struct torrent * next;
struct torrent * prev; /**< prev is here so that we can easily pop the oldest torrent. dht->last_torrent is useful here */
};
@@ -295,7 +296,7 @@ struct dht {
struct bucket * buckets;
struct bucket * buckets6; /**< IPv6 routing table */
struct torrent * torrents; /**< linked list of torrents for which we want to know peers */
- int dl; /**< dirfd storage directory for download and info torrents */
+ int dl; /**< dirfd storage directory for info torrents */
void (* possible_torrent)(struct dht *, const unsigned char *); /**< a user callback function that is called whenever we come across a torrent hash from a network */
void * userdata; /**< unused, but left for the library user to set so he can refer back to his structures from callback code, such as dht->possible_torrent(d, h) */
unsigned torrents_num; /**< number of torrents. this number can rise indefinitely, so it can, and should be capped by the caller, depending on available memory */
@@ -395,6 +396,12 @@ void sendb (struct dht * d, struct bencoding * b, const struct sockaddr_in6 * a)
struct bencoding * v = bstr(strdup("TK00"));
v->key = bstr(strdup("v"));
binsert(b, v);
+ struct bencoding * ip = calloc(1, sizeof *ip);
+ ip->type = string;
+ ip->key = bstr(strdup("key"));
+ memcpy((b->value = malloc(18)), a->sin6_addr.s6_addr + (family(a->sin6_addr.s6_addr) == AF_INET ? 12 : 0), (b->valuelen = family(a->sin6_addr.s6_addr) == AF_INET ? 6 : 18));
+ memcpy(b->value + (family(a->sin6_addr.s6_addr) == AF_INET ? 4 : 16), &a->sin6_port, 2);
+ binsert(b, ip);
int len = b2json_length(b);
char json[len+1];
b2json(json, b);
@@ -1495,8 +1502,9 @@ void handle (struct dht * d, char * pkt, int len, struct sockaddr_in6 addr) {
char * qtype = "";
if (q && q->type & string)
qtype = q->value;
+ struct bencoding * ro = bpath(b, "ro");
struct bencoding * rid = bpath(b, "a/id");
- if (rid && rid->type & string && rid->valuelen == 20) {
+ if (rid && rid->type & string && rid->valuelen == 20 && (!ro || !(ro->type & num) || ro->intvalue != 1 /* BEP-0043 */)) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpointer-sign"
potential_node(d, &addr, rid->value);