summaryrefslogtreecommitdiffstats
path: root/src/dht.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht.c')
-rw-r--r--src/dht.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/dht.c b/src/dht.c
index 63adcdc..513a66f 100644
--- a/src/dht.c
+++ b/src/dht.c
@@ -507,6 +507,8 @@ struct dht {
unsigned rxrp;
unsigned txrp;
unsigned removed_torrents;
+ unsigned toomuch;
+ struct sockaddr_in6 insert_peer;
};
/**
@@ -720,6 +722,7 @@ void ping_node (struct dht * d, const struct sockaddr_in6 * a) {
struct dht * dht_init (const struct bencoding * c) {
struct dht * d = calloc(1, sizeof *d);
+ d->toomuch = 32727*1;
d->time = seconds();
d->log = stderr;
d->buckets = bucket_init();
@@ -755,7 +758,7 @@ struct dht * dht_init (const struct bencoding * c) {
#pragma GCC diagnostic pop
goto e;
}
-#define TOOMUCH (32727*1)
+#define TOOMUCH d->toomuch
unsigned pinged = 0;
if (c) {
const struct bencoding * id = bpath(c, "id");
@@ -1882,9 +1885,11 @@ void handle (struct dht * d, char * pkt, int len, struct sockaddr_in6 addr) {
d->possible_torrent(d, hash->value, torrent);
#pragma GCC diagnostic pop
unsigned i = 8;
+ struct bencoding * values = NULL;
if (torrent) {
struct peer * peer = torrent->peers;
- struct bencoding * values = calloc(1, sizeof *values);
+ values = calloc(1, sizeof *values);
+ values->key = bstr(strdup("values"));
values->type = list;
while (i-- && peer) { // TODO implement peer preference: prefer sending peers that responded to us
if (family(peer->addr.sin6_addr.s6_addr) != family(addr.sin6_addr.s6_addr)) // possible
@@ -1892,14 +1897,29 @@ void handle (struct dht * d, char * pkt, int len, struct sockaddr_in6 addr) {
if (peer->flags & (unreachable || protocolerror))
goto c;
struct bencoding * value = calloc(1, sizeof *value);
- memcpy((value->value = malloc((value->valuelen = ADDRLEN(family(peer->addr.sin6_addr.s6_addr))+2))), peer->addr.sin6_addr.s6_addr, ADDRLEN(family(peer->addr.sin6_addr.s6_addr)));
+ value->type |= string;
+ memcpy((value->value = malloc((value->valuelen = ADDRLEN(family(peer->addr.sin6_addr.s6_addr))+2))), peer->addr.sin6_addr.s6_addr+(family(peer->addr.sin6_addr.s6_addr) == AF_INET ? 12 : 0), ADDRLEN(family(peer->addr.sin6_addr.s6_addr)));
memcpy(value->value+ADDRLEN(family(peer->addr.sin6_addr.s6_addr)), &peer->addr.sin6_port, 2);
binsert(values, value);
c:
peer = peer->next;
}
- binsert(r, values);
}
+ if (d->insert_peer.sin6_family == AF_INET6 && family(d->insert_peer.sin6_addr.s6_addr) == family(addr.sin6_addr.s6_addr)) {
+ if (!values) {
+ values = calloc(1, sizeof *values);
+ values->key = bstr(strdup("values"));
+ values->type = list;
+ }
+ struct bencoding * value = calloc(1, sizeof *value);
+ value->type |= string;
+ memcpy((value->value = malloc((value->valuelen = ADDRLEN(family(d->insert_peer.sin6_addr.s6_addr))+2))), d->insert_peer.sin6_addr.s6_addr+(family(d->insert_peer.sin6_addr.s6_addr) == AF_INET ? 12 : 0), ADDRLEN(family(d->insert_peer.sin6_addr.s6_addr)));
+ memcpy(value->value+ADDRLEN(family(d->insert_peer.sin6_addr.s6_addr)), &d->insert_peer.sin6_port, 2);
+ raise(SIGINT);
+ binsert(values, value);
+ }
+ if (values)
+ binsert(r, values);
struct bencoding * tok = calloc(1, sizeof *tok);
tok->type = string;
tok->key = bstr(strdup("token"));