diff options
Diffstat (limited to 'src/dht.c')
-rw-r--r-- | src/dht.c | 85 |
1 files changed, 22 insertions, 63 deletions
@@ -343,6 +343,7 @@ struct torrent { int recvd; /**< length of received data for current packet */ char * software; /**< can be read from disconnection() - software string client sent, may be NULL */ time_t ttl; /**< if nonzero, torrent will get his ->type cleared after this seconds() timestamp. set to seconds()+512 for example */ + unsigned canary; /**< for debugging purposes. assert that it's zero. set in free. */ }; /** @@ -404,6 +405,7 @@ void torrent_free (struct torrent * t) { } free(t->software); free(t->metadata); + t->canary = UINT_MAX; free(t); } @@ -448,6 +450,17 @@ void torrent_print (FILE * s, const struct torrent * t) { } /** + * assert that torrent linked list is correct and contains no freed structures + * + * @param t [in] first element of torrent linked list + */ + +void torrent_ll_assert (const struct torrent * t) { + for (; t != NULL; t = t->next) + assert(!t->canary); +} + +/** * what to log to FILE * from L() */ @@ -532,6 +545,7 @@ struct dht { unsigned txqp; unsigned rxrp; unsigned txrp; + unsigned removed_torrents; }; /** @@ -1172,7 +1186,7 @@ int bucket_grade (const struct dht * d, const struct bucket * b) { if (node_count(b->nodes) < K) return 0; struct node * n = b->nodes; - if (n) { + while (n) { if (node_grade(n) == bad) return 0; n = n->next; @@ -1321,6 +1335,8 @@ void remove_torrent (struct dht * d, struct torrent * t) { t->prev->next = t->next; if (t->next) t->next->prev = t->prev; + if (t == d->torrents) + d->torrents = t->next; struct peer * p = t->peers; while (p) { d->peers_num--; @@ -1328,6 +1344,8 @@ void remove_torrent (struct dht * d, struct torrent * t) { } d->torrents_num--; torrent_free(t); + torrent_ll_assert(d->torrents); + d->removed_torrents++; } /** @@ -1962,7 +1980,7 @@ void handle (struct dht * d, char * pkt, int len, struct sockaddr_in6 addr) { memcpy(&peer->addr, &addr, sizeof addr); if (bpath(b, "a/port") && (!bpath(b, "a/implied_port") || !bpath(b, "a/implied_port")->intvalue)) peer->addr.sin6_port = htons(bpath(b, "a/port")->intvalue); - peer = add_peer(d, torrent, peer); + add_peer(d, torrent, peer); break; default: // see NOTE01 ; @@ -2299,70 +2317,12 @@ void periodic (struct dht * d) { res_nclose(&state); // receiving and resolving SRV->{A,AAAA} in handle() } t: - ; + torrent_ll_assert(d->torrents); struct torrent * t = d->torrents; while (t) { if (t->ttl && seconds() > t->ttl) t->type = 0; if (t->type & (peers | announce)) { - /* - struct node * n = t->nodes; - int c = node_count(n); - if (!c) { -#define RTGP(buckets) {struct bucket * b = d->buckets; \ - find(t->hash, &b, NULL); \ - struct node * n = b->nodes; \ - c = node_count(n); \ - if (c) { \ - c = rand() % c; \ - while (c--) \ - n = n->next; \ - if (!n->unanswered) \ - n->last_sent = seconds(); \ - n->unanswered++; \ - get_peers(d, &n->addr, t->hash); \ - } else { \ - struct bucket * b = d->buckets; \ - c = 0; \ - while (b) { \ - c += node_count(b->nodes); \ - b = b->next; \ - } \ - if (c) { \ - c = rand() % c; \ - b = d->buckets; \ - int i = 0; \ - while (b) { \ - struct node * n = b->nodes; \ - while (n) { \ - if (i++ == c) { \ - i = -1; \ - if (!n->unanswered) \ - n->last_sent = seconds(); \ - n->unanswered++; \ - get_peers(d, &n->addr, t->hash); \ - break; \ - } \ - n = n->nodes; \ - } \ - if (i == -1) \ - break; \ - b = b->next; \ - } \ - } \ - } - RTGP(buckets); - RTGP(buckets6); - } else { - c = rand() % c; - while (c--) - n = n->next; - if (!n->unanswered) - n->last_sent = seconds(); - n->unanswered++; - get_peers(d, &n->addr, t->hash); - } - */ struct node * n = t->nodes; int sent = 0; while (n) { @@ -2463,8 +2423,7 @@ void periodic (struct dht * d) { t = t->next; } L(debug, d, "txqp=%u rxrp=%u rxqp=%u txrp=%u", d->txqp, d->rxrp, d->rxqp, d->txrp); - if (d->txqp > 16384 || d->rxrp > 16384 || d->rxqp > 16384 || d->txrp > 16384) - raise(SIGINT); + assert(!(d->txqp > 16384 || d->rxrp > 16384 || d->rxqp > 16384 || d->txrp > 16384)); d->txqp = d->txrp = d->rxqp = d->rxrp = 0; } |