diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/peers.c | 104 | ||||
| -rw-r--r-- | test/proto.c | 112 | ||||
| -rw-r--r-- | test/query.c | 84 | ||||
| -rw-r--r-- | test/routing.c | 8 |
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"); |
