0.0.002
ddat interop with dat js cable interop with cabal js ddat's frontend = dat-thang cable fe = cable-thang dillo support based on cel's dillo-dat bootstrap node xplatform support Signed-off-by: divo <418@cryspace.space>
This commit is contained in:
1 parent
f0f91540be
commit
b735900f2e
323 files changed
+134347
-343
No files matched your search
@@ -0,0 +1,234 @@
|
||||
#include "cesspool.h"
|
||||
#include "dat_wire.h"
|
||||
#include "sleep_crypto.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#include <sodium.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
typedef SOCKET test_socket_t;
|
||||
#else
|
||||
#include <unistd.h>
|
||||
typedef int test_socket_t;
|
||||
#endif
|
||||
|
||||
static uint16_t free_udp_port(void)
|
||||
{
|
||||
test_socket_t fd=socket(AF_INET,SOCK_DGRAM,0);struct sockaddr_in address;
|
||||
uint16_t port;
|
||||
#ifdef _WIN32
|
||||
int length=sizeof(address);
|
||||
assert(fd!=INVALID_SOCKET);
|
||||
#else
|
||||
socklen_t length=sizeof(address);
|
||||
assert(fd>=0);
|
||||
#endif
|
||||
memset(&address,0,sizeof(address));address.sin_family=AF_INET;address.sin_addr.s_addr=htonl(INADDR_LOOPBACK);
|
||||
assert(bind(fd,(struct sockaddr*)&address,sizeof(address))==0);assert(getsockname(fd,(struct sockaddr*)&address,&length)==0);
|
||||
port=ntohs(address.sin_port);
|
||||
#ifdef _WIN32
|
||||
closesocket(fd);
|
||||
#else
|
||||
close(fd);
|
||||
#endif
|
||||
return port;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
static const uint8_t hypercore[] = "hypercore";
|
||||
static const uint8_t namespace[] = DAT_NETWORK_PROTOCOL;
|
||||
uint8_t key[32], expected[32], actual[32], nonce[24], input[513];
|
||||
uint8_t whole[513], chunked[513];
|
||||
memset(key, 0x42, sizeof(key));
|
||||
#ifdef _WIN32
|
||||
{
|
||||
WSADATA winsock;
|
||||
assert(WSAStartup(MAKEWORD(2, 2), &winsock) == 0);
|
||||
}
|
||||
#endif
|
||||
assert(crypto_generichash(expected, sizeof(expected), hypercore,
|
||||
sizeof(hypercore) - 1, key, sizeof(key)) == 0);
|
||||
assert(sleep_compute_discovery_key(key, actual) == 0);
|
||||
assert(!memcmp(expected, actual, sizeof(actual)));
|
||||
/* Generated by extra/dillo-dat/node_modules/hypercore-crypto for a
|
||||
* 32-byte feed key filled with 0x42 (historical Dat v6/v7 stack). */
|
||||
{
|
||||
static const uint8_t js_hypercore_discovery_key[32] = {
|
||||
0xb0,0xfa,0xa6,0x16,0x21,0x2d,0x99,0x23,
|
||||
0x9f,0x50,0x7a,0x68,0x8f,0x50,0xcd,0x60,
|
||||
0xe6,0x51,0x4d,0xfb,0x62,0xae,0xf4,0xfc,
|
||||
0xfc,0x82,0x59,0xd6,0x46,0x96,0x35,0x91
|
||||
};
|
||||
assert(!memcmp(actual, js_hypercore_discovery_key, sizeof(actual)));
|
||||
}
|
||||
memset(nonce, 0x19, sizeof(nonce));
|
||||
for (size_t i = 0; i < sizeof(input); i++) input[i] = (uint8_t)(i * 37u + 11u);
|
||||
assert(sleep_stream_xsalsa20_xor(whole, input, sizeof(input), nonce, key, 0) == 0);
|
||||
{
|
||||
size_t offset = 0;
|
||||
static const size_t pieces[] = {1, 63, 64, 65, 127, 193};
|
||||
for (size_t i = 0; i < sizeof(pieces) / sizeof(pieces[0]); i++) {
|
||||
assert(sleep_stream_xsalsa20_xor(chunked + offset, input + offset,
|
||||
pieces[i], nonce, key, offset) == 0);
|
||||
offset += pieces[i];
|
||||
}
|
||||
assert(offset == sizeof(input));
|
||||
}
|
||||
assert(!memcmp(whole, chunked, sizeof(whole)));
|
||||
{
|
||||
cesspool_t transactions;
|
||||
uint16_t id;
|
||||
memset(&transactions, 0, sizeof(transactions));
|
||||
assert(cesspool_transaction_begin(&transactions, CESSPOOL_LOOKUP, key,
|
||||
100, &id) == 0);
|
||||
assert(cesspool_transaction_finish(&transactions, id) == 0);
|
||||
assert(cesspool_transaction_begin(&transactions, CESSPOOL_PING, key,
|
||||
10, &id) == 0);
|
||||
assert(cesspool_tick(&transactions, 10) == 0);
|
||||
errno = 0;
|
||||
assert(cesspool_transaction_finish(&transactions, id) != 0 && errno == ENOENT);
|
||||
}
|
||||
assert(crypto_generichash(expected, sizeof(expected), namespace,
|
||||
sizeof(namespace) - 1, key, sizeof(key)) == 0);
|
||||
assert(cesspool_discovery_key(key, actual) == 0);
|
||||
assert(!memcmp(expected, actual, sizeof(actual)));
|
||||
{
|
||||
cesspool_t relay, publisher, lookup;
|
||||
cesspool_peer_t *peers[4];
|
||||
uint8_t relay_id[32] = {0x10}, publisher_id[32] = {0x11}, lookup_id[32] = {0x22};
|
||||
uint8_t topic[32] = {0x33}, archive_topic_a[32] = {0x34};
|
||||
uint8_t archive_topic_b[32] = {0x35};
|
||||
uint8_t packet[80];
|
||||
cesspool_message_t message, decoded;
|
||||
size_t packet_len;
|
||||
uint16_t relay_port = free_udp_port(), publisher_port = free_udp_port(), lookup_port = free_udp_port();
|
||||
assert(cesspool_init(&relay, relay_id) == 0);
|
||||
assert(cesspool_init(&publisher, publisher_id) == 0);
|
||||
assert(cesspool_init(&lookup, lookup_id) == 0);
|
||||
assert(cesspool_listen(&relay, "localhost", relay_port) == 0);
|
||||
assert(cesspool_listen(&publisher, "localhost", publisher_port) == 0);
|
||||
assert(cesspool_listen(&lookup, "localhost", lookup_port) == 0);
|
||||
assert(relay_port && publisher_port && lookup_port && relay_port != publisher_port && relay_port != lookup_port && publisher_port != lookup_port);
|
||||
assert(cesspool_set_bootstrap_server(&relay, 1) == 0);
|
||||
assert(cesspool_add_bootstrap(&publisher, "localhost", relay_port) == 0);
|
||||
assert(cesspool_add_bootstrap(&lookup, "127.0.0.1", relay_port) == 0);
|
||||
/* A third party's REPLY packet must not mark the configured node
|
||||
* online or inject forged rendezvous entries. */
|
||||
{
|
||||
cesspool_message_t forged;
|
||||
uint8_t forged_packet[80];
|
||||
size_t forged_length;
|
||||
struct sockaddr_in *target;
|
||||
dat_peer_t forged_target;
|
||||
memset(&forged, 0, sizeof(forged));
|
||||
forged.type = CESSPOOL_REPLY;
|
||||
memcpy(forged.peer_id, publisher_id, sizeof(publisher_id));
|
||||
memcpy(forged.topic, topic, sizeof(topic));
|
||||
forged.payload[0] = 0x1a; /* malformed one-byte peer record */
|
||||
forged.payload[1] = 0x01;
|
||||
forged.payload[2] = 0xff;
|
||||
forged.payload_len = 3;
|
||||
assert(cesspool_encode(&forged, forged_packet, sizeof(forged_packet), &forged_length) == 0);
|
||||
memset(&forged_target, 0, sizeof(forged_target));
|
||||
target = (struct sockaddr_in *)&forged_target.addr;
|
||||
target->sin_family = AF_INET;
|
||||
target->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
target->sin_port = htons(lookup_port);
|
||||
forged_target.addrlen = sizeof(*target);
|
||||
assert(datnet_send(&publisher.net, &forged_target, forged_packet, forged_length) == 0);
|
||||
assert(cesspool_poll(&lookup, 100) >= 0);
|
||||
assert(!lookup.bootstrap_reachable && lookup.announcement_count == 0);
|
||||
}
|
||||
assert(cesspool_join(&publisher, topic, publisher_port, 1, 0) == 0);
|
||||
assert(cesspool_poll(&relay, 100) >= 0);
|
||||
/* One client identity may announce a room and multiple archives. The
|
||||
* rendezvous counters must report one peer across three distinct topics. */
|
||||
assert(cesspool_join(&publisher, archive_topic_a, publisher_port, 1, 0) == 0);
|
||||
assert(cesspool_poll(&relay, 100) >= 0);
|
||||
assert(cesspool_join(&publisher, archive_topic_b, publisher_port, 1, 0) == 0);
|
||||
assert(cesspool_poll(&relay, 100) >= 0);
|
||||
assert(cesspool_announced_peer_count(&relay) == 1);
|
||||
assert(cesspool_announced_topic_count(&relay) == 3);
|
||||
assert(cesspool_join(&lookup, topic, lookup_port, 0, 1) == 0);
|
||||
assert(cesspool_poll(&relay, 100) >= 0);
|
||||
assert(cesspool_poll(&lookup, 100) >= 0);
|
||||
assert(lookup.bootstrap_reachable);
|
||||
assert(cesspool_topic_peers(&lookup, topic, peers, 4) >= 1);
|
||||
assert(!memcmp(peers[0]->public_key, publisher_id, 32));
|
||||
/* Expiring the lookup record must clear the client's Discovered row. */
|
||||
for (size_t a = 0; a < lookup.announcement_count; a++)
|
||||
lookup.announcements[a].last_seen = 0;
|
||||
lookup.bootstrap_count = 0;
|
||||
for (size_t t = 0; t < lookup.topic_count; t++)
|
||||
lookup.topics[t].refresh_at = UINT64_MAX;
|
||||
assert(cesspool_tick(&lookup, 0) == 0);
|
||||
assert(cesspool_topic_peers(&lookup, topic, peers, 4) == 0);
|
||||
assert(!cesspool_find_peer(&lookup, publisher_id)->discovered);
|
||||
assert(cesspool_leave(&publisher, archive_topic_a) == 0);
|
||||
assert(cesspool_poll(&relay, 100) >= 0);
|
||||
assert(cesspool_announced_peer_count(&relay) == 1);
|
||||
assert(cesspool_announced_topic_count(&relay) == 2);
|
||||
assert(cesspool_tick(&relay, UINT64_MAX) == 0);
|
||||
assert(cesspool_announced_peer_count(&relay) == 1); /* Fresh announcements keep it live. */
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.type = CESSPOOL_PING;
|
||||
assert(cesspool_encode(&message, packet, sizeof(packet), &packet_len) == 0);
|
||||
assert(packet_len == 72);
|
||||
assert(cesspool_decode(&decoded, packet, packet_len) == 0);
|
||||
assert(decoded.type == CESSPOOL_PING);
|
||||
assert(cesspool_decode(&decoded, packet, packet_len + 1) != 0);
|
||||
memset(&message, 0, sizeof(message));
|
||||
message.type = CESSPOOL_REPLY;
|
||||
message.payload_len = sizeof(message.payload);
|
||||
assert(cesspool_encode(&message, packet, sizeof(packet), &packet_len) != 0);
|
||||
assert(cesspool_leave(&publisher, topic) == 0);
|
||||
assert(cesspool_leave(&publisher, archive_topic_b) == 0);
|
||||
assert(cesspool_leave(&lookup, topic) == 0);
|
||||
assert(cesspool_destroy(&relay) == 0);
|
||||
assert(cesspool_destroy(&publisher) == 0);
|
||||
assert(cesspool_destroy(&lookup) == 0);
|
||||
}
|
||||
{
|
||||
cesspool_t routing;
|
||||
cesspool_response_t response;
|
||||
cesspool_peer_t *closest[4];
|
||||
uint8_t local_prefix[2] = {192, 168}, local_id[32] = {0};
|
||||
struct sockaddr_in *address;
|
||||
memset(&response, 0, sizeof(response));
|
||||
response.peers_len = 6;
|
||||
response.peers[0] = 127; response.peers[3] = 1;
|
||||
response.peers[4] = 0x0c; response.peers[5] = 0xd2;
|
||||
response.local_peers_len = 4;
|
||||
response.local_peers[0] = 10; response.local_peers[1] = 1;
|
||||
response.local_peers[2] = 0x0c; response.local_peers[3] = 0xd2;
|
||||
assert(cesspool_init(&routing, local_id) == 0);
|
||||
assert(cesspool_process_response(&routing, &response, local_prefix) == 0);
|
||||
assert(routing.peer_count == 2 && routing.peers[1].local);
|
||||
address = (struct sockaddr_in *)&routing.peers[1].address.addr;
|
||||
assert(ntohs(address->sin_port) == 3282);
|
||||
assert(((uint8_t *)&address->sin_addr)[0] == 192 &&
|
||||
((uint8_t *)&address->sin_addr)[1] == 168 &&
|
||||
((uint8_t *)&address->sin_addr)[2] == 10 &&
|
||||
((uint8_t *)&address->sin_addr)[3] == 1);
|
||||
assert(cesspool_closest(&routing, local_id, closest, 4) == 2);
|
||||
assert(cesspool_destroy(&routing) == 0);
|
||||
}
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
Reference in new issue
Block a user