summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJesper Jensen <jesper@jnsn.dev>2023-07-23 12:15:34 +0200
committerJesper Jensen <jesper@jnsn.dev>2025-04-12 10:21:20 +0200
commit47d4780eb448f839fc6b0644135395f879080ba4 (patch)
tree2c9a84bf45a4b8af5411331db50173fc5a34f630 /test
parent3515701479fe04f73e9194ee3074457bb85030f6 (diff)
I don't remember
Diffstat (limited to 'test')
-rw-r--r--test/peers.c104
-rw-r--r--test/proto.c112
-rw-r--r--test/query.c84
-rw-r--r--test/routing.c8
4 files changed, 291 insertions, 17 deletions
diff --git a/test/peers.c b/test/peers.c
new file mode 100644
index 0000000..1e9a454
--- /dev/null
+++ b/test/peers.c
@@ -0,0 +1,104 @@
+#include "unity.h"
+#include "peers.h"
+#include "log.h"
+
+#include <string.h>
+#include <arpa/inet.h>
+
+#define IP(a, b, c, d) htonl(a << 24 | b << 16 | c << 8 | d)
+
+void test_add_single_peer() {
+ allocate_hashtable();
+
+ struct infohash sometorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
+ struct addr addr = (struct addr){.ip = IP(128,0,0,1), .port = 0};
+
+ int rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+}
+
+void test_add_9_peers_same_torrent() {
+ allocate_hashtable();
+
+ struct infohash sometorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
+ struct addr addr = (struct addr){.ip = IP(128,0,0,1), .port = 0};
+
+ int rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ // There's room for 8 peers per infohash
+ rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(PEER_EFULL, rc);
+}
+
+void test_peers_for_only_torrent() {
+ allocate_hashtable();
+
+ struct infohash sometorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
+ struct infohash othertorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00522}};
+ struct addr someaddr = (struct addr){.ip = IP(128,0,0,1), .port = 0};
+ struct addr otheraddr = (struct addr){.ip = IP(128,0,0,1), .port = 1};
+
+ int rc = add_peer(&sometorrent, &someaddr);
+ TEST_ASSERT_EQUAL(0, rc);
+ rc = add_peer(&othertorrent, &otheraddr);
+ TEST_ASSERT_EQUAL(0, rc);
+
+ struct addr* found;
+ size_t found_len;
+
+ get_peers(&sometorrent, &found, &found_len);
+ TEST_ASSERT_EQUAL(1, found_len);
+ TEST_ASSERT_EQUAL_MEMORY(&someaddr, &found[0], sizeof(struct addr));
+
+ get_peers(&othertorrent, &found, &found_len);
+ TEST_ASSERT_EQUAL(1, found_len);
+ TEST_ASSERT_EQUAL_MEMORY(&otheraddr, &found[0], sizeof(struct addr));
+}
+
+void test_have_no_peers() {
+ allocate_hashtable();
+
+ struct infohash sometorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
+
+ struct addr* found;
+ size_t found_len;
+ get_peers(&sometorrent, &found, &found_len);
+ TEST_ASSERT_NULL(found);
+ TEST_ASSERT_EQUAL(0, found_len);
+}
+
+void test_grows() {
+ allocate_hashtable();
+
+ struct addr addr = (struct addr){.ip = IP(128,0,0,1), .port = 0};
+
+ for(int i = 0; i < 17; i++) { // Peer table size + 1 to make sure it HAS to grow
+ struct infohash sometorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, i}};
+ int rc = add_peer(&sometorrent, &addr);
+ TEST_ASSERT_EQUAL(0, rc);
+ }
+
+ {
+ // We can find a peer after the resize again
+ struct infohash sometorrent = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x00000001}};
+ struct addr* found;
+ size_t found_len;
+ get_peers(&sometorrent, &found, &found_len);
+ TEST_ASSERT_NOT_NULL(found);
+ TEST_ASSERT_EQUAL(1, found_len);
+ }
+}
diff --git a/test/proto.c b/test/proto.c
index 60fa1cd..49a77b9 100644
--- a/test/proto.c
+++ b/test/proto.c
@@ -1,10 +1,13 @@
#include "unity.h"
#include "proto.h"
+#include "peers.h"
#include "log.h"
#include <string.h>
+#define IP(a, b, c, d) htonl(a << 24 | b << 16 | c << 8 | d)
+
void test_begin_pings_bootstrap_node() {
struct message outbuff[10] = {0};
@@ -222,7 +225,7 @@ void test_remove_from_routing_after_3_retries() {
{
// The node responds
// We return no new nodes to stop any new pings from going out
- char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:""ee";
+ char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:ee";
struct message* message_cursor = outbuff;
proto_run(&dht, buff, sizeof(buff), (struct sockaddr_in*)&remote, remote_len, now, &message_cursor, outbuff+2);
}
@@ -258,7 +261,7 @@ void test_remove_from_routing_after_3_retries() {
struct message* message_cursor = outbuff;
proto_run(&dht, NULL, 0, (struct sockaddr_in*)NULL, 0, now, &message_cursor, outbuff+2);
- TEST_ASSERT_EQUAL_PTR_MESSAGE(message_cursor, outbuff, "The timeout should send a message");
+ TEST_ASSERT_EQUAL_PTR_MESSAGE(message_cursor, outbuff, "The timeout should send not a message");
entry = routing_get(&other);
TEST_ASSERT_NULL(entry);
}
@@ -286,7 +289,7 @@ void test_ping_node_when_uncertain() {
{
// The node responds
// We return no new nodes to stop any new pings from going out
- char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:""ee";
+ char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:ee";
struct message* message_cursor = outbuff;
proto_run(&dht, buff, sizeof(buff), (struct sockaddr_in*)&remote, remote_len, now, &message_cursor, outbuff+2);
}
@@ -309,7 +312,7 @@ void test_ping_node_when_uncertain() {
now += 5;
{
// The node responds
- char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:""ee";
+ char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:ee";
struct message* message_cursor = outbuff;
proto_run(&dht, buff, sizeof(buff), (struct sockaddr_in*)&remote, remote_len, now, &message_cursor, outbuff+2);
@@ -343,7 +346,7 @@ void test_query_find_node() {
{
// The node responds
// We return no new nodes to stop any new pings from going out
- char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:""ee";
+ char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:ee";
struct message* message_cursor = outbuff;
proto_run(&dht, buff, sizeof(buff), (struct sockaddr_in*)&remote, remote_len, now, &message_cursor, outbuff+2);
}
@@ -370,3 +373,102 @@ void test_query_find_node() {
TEST_ASSERT_EQUAL_CHAR_ARRAY("ee", outbuff[0].payload+81, 2);
}
}
+
+void test_query_get_peers_have_one() {
+ struct message outbuff[10] = {0};
+ time_t now = 0;
+
+ struct sockaddr_storage remote;
+ socklen_t remote_len;
+
+ allocate_hashtable();
+
+ struct dht dht;
+ dht.self = (struct nodeid){.inner={0x42424242, 0x42424242, 0x42424242, 0x42424242, 0x42424242}};
+ routing_init(&dht.self);
+
+ {
+ struct message* message_cursor = outbuff;
+ proto_begin(&dht, 0, &message_cursor, outbuff+2);
+ remote_len = outbuff[0].dest_len;
+ memcpy(&remote, &outbuff[0].dest, remote_len);
+ }
+ now += 10;
+
+ {
+ // The node responds
+ // We return no new nodes to stop any new pings from going out
+ char buff[] = "d1:y1:r1:t1:01:rd2:id20:aaaaaaaaaaaaaaaaaaaa5:nodes0:ee";
+ struct message* message_cursor = outbuff;
+ proto_run(&dht, buff, sizeof(buff), (struct sockaddr_in*)&remote, remote_len, now, &message_cursor, outbuff+2);
+ }
+ now += 1;
+
+ // Some other node then asks for peers
+ {
+ struct sockaddr_in other;
+ other.sin_family = AF_INET;
+ inet_pton(AF_INET, "128.0.0.1", &other.sin_addr.s_addr);
+ other.sin_port = htons(9090);
+
+ // Node asks for peers to get token
+ char buff[] = "d1:ad2:id20:abcdefghij01234567899:info_hash20:aaaaaaaaaaaaaaaaaaaae1:q9:get_peers1:t2:aa1:y1:qe";
+ struct message* message_cursor = outbuff;
+ proto_run(&dht, buff, sizeof(buff), &other, sizeof(other), 0, &message_cursor, outbuff+2);
+
+ // We should have sent a response
+ TEST_ASSERT_EQUAL_PTR(message_cursor, outbuff+1);
+
+ TEST_ASSERT_EQUAL(93, outbuff[0].payload_len);
+ char* cursor = outbuff[0].payload;
+ TEST_ASSERT_EQUAL_CHAR_ARRAY("d1:t2:aa1:y1:r1:rd2:id20:BBBBBBBBBBBBBBBBBBBB5:token1:t5:nodes26:aaaaaaaaaaaaaaaaaaaa", cursor, 85);
+ cursor+=85;
+ TEST_ASSERT_EQUAL_MEMORY(&((struct sockaddr_in*)&remote)->sin_addr.s_addr, cursor, 4);
+ cursor+=4;
+ TEST_ASSERT_EQUAL_MEMORY(&((struct sockaddr_in*)&remote)->sin_port, cursor, 2);
+ cursor+=2;
+ TEST_ASSERT_EQUAL_CHAR_ARRAY("ee", cursor, 2);
+ cursor+=2;
+ }
+ now += 1;
+
+ // Using the token from before that node then announces that it's a peer
+ {
+ struct sockaddr_in other;
+ other.sin_family = AF_INET;
+ inet_pton(AF_INET, "128.0.0.1", &other.sin_addr.s_addr);
+ other.sin_port = htons(9090);
+
+ // Node announces that it's a peer for that torrent
+ char buff[] = "d1:ad2:id20:abcdefghij012345678912:implied_porti1e9:info_hash20:aaaaaaaaaaaaaaaaaaaa4:porti1337e5:token1:te1:q13:announce_peer1:t2:aa1:y1:qe";
+ struct message* message_cursor = outbuff;
+ proto_run(&dht, buff, sizeof(buff), (struct sockaddr_in*)&other, sizeof(other), now, &message_cursor, outbuff+2);
+ TEST_ASSERT_EQUAL_PTR(message_cursor, outbuff+1);
+
+ TEST_ASSERT_EQUAL(47, outbuff[0].payload_len);
+ char* cursor = outbuff[0].payload;
+ TEST_ASSERT_EQUAL_CHAR_ARRAY("d1:t2:aa1:y1:r1:rd2:id20:BBBBBBBBBBBBBBBBBBBBee", cursor, 47);
+ cursor+=47;
+ }
+ now += 1;
+
+ // A third node should now get that peer when asking
+ {
+ struct sockaddr_in other;
+ other.sin_family = AF_INET;
+ inet_pton(AF_INET, "255.255.255.255", &other.sin_addr.s_addr);
+ other.sin_port = htons(6881);
+
+ char buff[] = "d1:ad2:id20:abcdefghij01234567899:info_hash20:aaaaaaaaaaaaaaaaaaaae1:q9:get_peers1:t2:aa1:y1:qe";
+ struct message* message_cursor = outbuff;
+ proto_run(&dht, buff, sizeof(buff), &other, sizeof(other), 0, &message_cursor, outbuff+2);
+
+ // We should have sent a response
+ TEST_ASSERT_EQUAL_PTR(message_cursor, outbuff+1);
+
+ TEST_ASSERT_EQUAL(75, outbuff[0].payload_len);
+ char* cursor = outbuff[0].payload;
+ TEST_ASSERT_EQUAL_CHAR_ARRAY("d1:t2:aa1:y1:r1:rd2:id20:BBBBBBBBBBBBBBBBBBBB5:token1:t6:valuesl6:\x80\x00\x00\x01\x23\x82""eee", cursor, 75);
+ cursor+=75;
+ }
+}
diff --git a/test/query.c b/test/query.c
index 5744fba..a3d3bb9 100644
--- a/test/query.c
+++ b/test/query.c
@@ -3,8 +3,18 @@
#include "query.h"
#include <string.h>
+#include <arpa/inet.h>
+
+#define IP(a, b, c, d) htonl(a << 24 | b << 16 | c << 8 | d)
void test_malformed_empty() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "";
size_t packet_len = 0;
@@ -13,12 +23,19 @@ void test_malformed_empty() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_malformed_only_dict_start() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "d";
size_t packet_len = 1;
@@ -27,12 +44,19 @@ void test_malformed_only_dict_start() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_malformed_empty_args_key() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "d1:ae";
size_t packet_len = strlen(packet);
@@ -41,12 +65,19 @@ void test_malformed_empty_args_key() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_malformed_wrong_args_type() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "d1:a1:re";
size_t packet_len = strlen(packet);
@@ -55,12 +86,19 @@ void test_malformed_wrong_args_type() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_malformed_empty_args() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "d1:adee";
size_t packet_len = strlen(packet);
@@ -69,12 +107,19 @@ void test_malformed_empty_args() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_malformed_wrong_id_arg_type() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "d1:ad2:idi1eee";
size_t packet_len = strlen(packet);
@@ -83,12 +128,19 @@ void test_malformed_wrong_id_arg_type() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_malformed_wrong_id_length() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner={0x0034048f, 0x08000020, 0x00888880, 0x02008460, 0x0ab00521}};
char* packet = "d1:ad2:id19:aaaaaaaaaaaaaaaaaaaee";
size_t packet_len = strlen(packet);
@@ -97,12 +149,19 @@ void test_malformed_wrong_id_length() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EBADQ, rc);
}
void test_ping() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner_b={"aaaaaaaaaaaaaaaaaaab"}};
char* packet = "d1:ad2:id20:aaaaaaaaaaaaaaaaaaaaee";
size_t packet_len = strlen(packet);
@@ -111,7 +170,7 @@ void test_ping() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "ping", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "ping", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(0, rc);
TEST_ASSERT_EQUAL(29, response_cursor - response);
@@ -119,6 +178,13 @@ void test_ping() {
}
void test_bad_method() {
+
+ struct sockaddr_in src = {
+ .sin_family = AF_INET,
+ .sin_addr.s_addr = IP(255, 0, 0, 1),
+ .sin_port = 6881,
+ };
+
struct nodeid self = {.inner_b={"aaaaaaaaaaaaaaaaaaab"}};
char* packet = "de";
size_t packet_len = strlen(packet);
@@ -127,7 +193,7 @@ void test_bad_method() {
char* response_cursor = response;
char* response_end = response + sizeof(response);
- int rc = handle_request(&self, "someWrongMethod", packet, packet_len, &response_cursor, response_end-response_cursor);
+ int rc = handle_request(&self, "someWrongMethod", (struct sockaddr*)&src, sizeof(src), packet, packet_len, &response_cursor, response_end-response_cursor);
TEST_ASSERT_EQUAL(QUERY_EUNK, rc);
}
diff --git a/test/routing.c b/test/routing.c
index ad6f2c3..4613848 100644
--- a/test/routing.c
+++ b/test/routing.c
@@ -1,7 +1,9 @@
#include "unity.h"
#include "routing.h"
-#define IP(a, b, c, d) (a << 24 | b << 16 | c << 8 | d)
+#include <arpa/inet.h>
+
+#define IP(a, b, c, d) htonl(a << 24 | b << 16 | c << 8 | d)
struct nodeid self;
@@ -229,7 +231,7 @@ void test_close_to_self_load_factor() {
// Make a nodeid that is one bit different
struct nodeid new = self;
- new.inner[4] += 1;
+ new.inner[4] += ntohl(1);
struct entry* entry;
TEST_ASSERT_TRUE_MESSAGE(routing_offer(&new, &entry), "Did not accept new entry");
@@ -260,7 +262,7 @@ void test_far_from_self_load_factor() {
struct nodeid new = self;
// Flip top bit to make it very dissimilar
- new.inner[0] ^= 0x80000000;
+ new.inner[0] ^= ntohl(0x80000000);
struct entry* entry;
TEST_ASSERT_TRUE_MESSAGE(routing_offer(&new, &entry), "Did not accept new entry");