summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/dht.c87
-rw-r--r--src/main.c7
2 files changed, 57 insertions, 37 deletions
diff --git a/src/dht.c b/src/dht.c
index 83fcb68..4e57e5e 100644
--- a/src/dht.c
+++ b/src/dht.c
@@ -794,6 +794,8 @@ struct dht * dht_init (const struct bencoding * c) {
#pragma GCC diagnostic pop
goto e;
}
+#define TOOMUCH 32727
+ unsigned pinged = 0;
if (c) {
const struct bencoding * id = bpath(c, "id");
if (id && id->type & string && id->valuelen == 20)
@@ -811,7 +813,7 @@ struct dht * dht_init (const struct bencoding * c) {
.sin6_family = AF_INET6,
.sin6_port = htons(atoi(++port))
};
- if (inet_pton(AF_INET6, remote, addr.sin6_addr.s6_addr) == 1)
+ if (inet_pton(AF_INET6, remote, addr.sin6_addr.s6_addr) == 1 && pinged++ < TOOMUCH/2)
ping_node(d, &addr);
}
}
@@ -2172,6 +2174,30 @@ d:
} // do not log, it may have been a bencoded reply
}
+/**
+ * delete all but first bucket in ll, used in refresh on both lls (v4 and v6) in case of sybil
+ *
+ * @param b [in] first bucket in ll
+ */
+
+void delete_buckets (struct bucket * b) {
+ struct node * n = b->nodes;
+ while (n) {
+ struct node * old = n;
+ n = n->next;
+ node_free(old);
+ }
+ b->nodes = NULL;
+ memset(b->id, '\0', 20);
+ struct bucket * del = b->next;
+ b->next = NULL;
+ while (del) {
+ struct bucket * old = del;
+ del = del->next;
+ bucket_free(old);
+ }
+}
+
#define PERIODIC 10
/**
@@ -2214,33 +2240,10 @@ int refresh (struct dht * d, int fam) {
if (buckets > 64) { // sybil attack - node is broken - clear whole routing table, keeping one bucket
dht_print(d->log, d);
L(disagreement, d, "@@@@@@ SYBIL ATTACK - CLEARING ROUTING TABLE @@@@@@");
- int keep_first = rand() % 2; // should we even keep one bucket? the sybil node has a 1/2
- if (keep_first) { // chance of having stared in the bucket farthest away, so it's stored there ...
- memset(d->buckets->id, '\0', 20);
- b = d->buckets->next;
- d->buckets->next = NULL;
- while (b) {
- bucket_free(b);
- b = b->next;
- }
- } else {
- b = d->buckets;
- while (b->next) {
- struct bucket * old = b;
- b = b->next;
- bucket_free(old);
- }
- d->buckets = b;
- memset(d->buckets->id, '\0', 20);
- }
+ delete_buckets(d->buckets);
+ delete_buckets(d->buckets6);
if (getrandom(d->id, 20, GRND_NONBLOCK) == -1) // changing our ID. note that this might make
- L(std_fail, d, "getrandom: %s", strerror(errno)); // existing nodes hate us
- switch (fam) {
- case AF_INET:
- return node_count(d->buckets6->nodes);
- case AF_INET6:
- return node_count(d->buckets6->nodes);
- }
+ L(std_fail, d, "getrandom: %s", strerror(errno)); // existing nodes hate us, though we'll probably have no existing nodes
return 0;
}
return nrgood;
@@ -2337,25 +2340,36 @@ void periodic (struct dht * d) {
if (t->type & (peers | announce)) {
struct node * n = t->nodes;
int sent = 0;
- while (n) {
- sent++;
+ int c = node_count(n);
+ if (c)
+ c = rand() % c;
+ while (n && c--)
+ n = n->next;
+ if (n && sent < 3) { // we pick some consecutive at random and ping them.
+ sent++; // increase to more than this if desired ... idk this is shit
if (!n->unanswered)
n->last_sent = seconds();
n->unanswered++;
get_peers(d, &n->addr, t->hash);
n = n->next;
+ if (!n && !t->nodes->unanswered) // if unanswered, we already sent it
+ n = t->nodes;
}
- if (sent < 1) {
+ if (sent < 2) {
#define RTGP(buckets) {struct bucket * b = d->buckets; \
find(t->hash, &b, NULL); \
struct node * n = b->nodes; \
- while (sent < 1 && n) { \
+ int c = node_count(n); \
+ if (c) \
+ c = rand() % c; \
+ while (n && c--) \
+ n = n->next; \
+ if (n) { \
sent++; \
if (!n->unanswered) \
n->last_sent = seconds(); \
n->unanswered++; \
get_peers(d, &n->addr, t->hash); \
- n = n->next; \
}}
RTGP(buckets);
RTGP(buckets6);
@@ -2364,13 +2378,17 @@ void periodic (struct dht * d) {
struct bucket * b = d->buckets;
while (sent < 1 && b) {
n = b->nodes;
- while (sent < 1 && n) {
+ int c = node_count(n);
+ if (c)
+ c = rand() % c;
+ while (n && c--)
+ n = n->next;
+ if (sent < 1 && n) {
sent++;
if (!n->unanswered)
n->last_sent = seconds();
n->unanswered++;
get_peers(d, &n->addr, t->hash);
- n = n->next;
}
b = b->next;
}
@@ -2435,7 +2453,6 @@ 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);
-#define TOOMUCH 32727
if (d->txqp > TOOMUCH || d->rxrp > TOOMUCH || d->rxqp > TOOMUCH || d->txrp > TOOMUCH) {
dht_print(stdout, d);
raise(SIGABRT);
diff --git a/src/main.c b/src/main.c
index 4e9c188..de21f7a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -45,7 +45,7 @@ void found_torrent (struct dht * d __attribute__((unused)), const unsigned char
L(debug, d, "%s%s", buf, t ? " stored" : " new");
if (t) {
if (!t->type)
- t->ttl = seconds()+128;
+ t->ttl = seconds()+256;
t->type |= info | peers;
} else {
if (last_added + 1 > seconds()) {
@@ -56,7 +56,7 @@ void found_torrent (struct dht * d __attribute__((unused)), const unsigned char
t = torrent_init();
memcpy(t->hash, h, 20);
t->type |= info | peers;
- t->ttl = seconds()+128;
+ t->ttl = seconds()+256;
add_torrent(d, t);
}
}
@@ -135,6 +135,7 @@ int main (int argc, char ** argv) {
struct torrent * torrent = torrent_init();
memcpy(torrent->hash, "\xdd\x82\x55\xec\xdc\x7c\xa5\x5f\xb0\xbb\xf8\x13\x23\xd8\x70\x62\xdb\x1f\x6d\x1c", 20);
torrent->type = /* (useless, since we have no listening system yet) announce | */ peers | info;
+ torrent->ttl = seconds()+128; /**< idk, enough to bootstrap i guess */
add_torrent(dht, torrent);
periodic(dht);
// alarm(PERIODIC);
@@ -143,6 +144,7 @@ w:
if (sigusr1) {
sigusr1 = 0;
dht_print(stdout, dht);
+ fflush(stdout);
goto w;
}
if (periodično) {
@@ -160,6 +162,7 @@ w:
if (sigusr1) {
sigusr1 = 0;
dht_print(stdout, dht);
+ fflush(stdout);
goto w;
}
if (periodično) {