diff options
Diffstat (limited to 'src/dht.c')
-rw-r--r-- | src/dht.c | 28 |
1 files changed, 24 insertions, 4 deletions
@@ -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")); |