summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar moon <moon@coffin.ir> 2025-09-14 22:56:09 +0330
committerGravatar moon <moon@coffin.ir> 2025-09-14 22:56:09 +0330
commitdae22b776a8322029a3f2b33fbb6738c848dd4a3 (patch)
tree27109873037214e10705f06967ccc712cb1cda5d
parentstuff (diff)
🎶 iiiii waaas goinggg insaaaaaaaane
-rw-r--r--client/3rd-party/client.ts2
-rw-r--r--client/client.c17
-rw-r--r--client/client.h7
-rw-r--r--src/common.c15
-rw-r--r--src/external.h53
-rw-r--r--src/packet_storage.c72
-rw-r--r--src/server.c6
7 files changed, 104 insertions, 68 deletions
diff --git a/client/3rd-party/client.ts b/client/3rd-party/client.ts
index 34bfc91..aac49c5 100644
--- a/client/3rd-party/client.ts
+++ b/client/3rd-party/client.ts
@@ -3,7 +3,7 @@
const MAX_BUFFER = 1 << 18;
const MAX_BODY = 1 << 22;
const MAX_RECIPIENTS = 32;
-const PACKET_SIZE = 4 + 32 + (1 + 8 + 32 + 32 + 1 + (32 * MAX_RECIPIENTS) + 65536 + 64);
+const PACKET_SIZE = 4 + 32 + (1 + 8 + 32 + 32 + 1 + (64 * MAX_RECIPIENTS) + 65536 + 64);
const RELAY_NEIGHBOR_WIRE_LEN = 1 + 1 + 1 + 4 + 16 + 2;
enum MpClientError {
diff --git a/client/client.c b/client/client.c
index 155d895..c7a2836 100644
--- a/client/client.c
+++ b/client/client.c
@@ -423,7 +423,7 @@ struct data_packet mp_create_packet_from_bytes(
const byte *input,
size_t input_len,
byte recipient_count,
- hash *recipients,
+ recipient *recipients,
keypair author_keys) {
struct data_packet packet;
memset(&packet, 0, sizeof(packet));
@@ -434,7 +434,7 @@ struct data_packet mp_create_packet_from_bytes(
packet.contents.recipient_count
= recipient_count > MAX_RECIPIENTS ? MAX_RECIPIENTS : recipient_count;
if (recipients)
- memcpy(packet.contents.recipients, recipients, packet.contents.recipient_count * 32);
+ memcpy(packet.contents.recipients, recipients, packet.contents.recipient_count * 64);
packet.contents.created_time_ms = get_current_time_ms();
@@ -442,7 +442,6 @@ struct data_packet mp_create_packet_from_bytes(
memcpy(packet.contents.author_signing_pub, author_keys.signing_pub, sizeof(public_key));
packet.contents.encrypted = false;
- // Create signature
size_t msg_len = CONTENTS_SIZE - sizeof(signature);
byte *msg_buf = malloc(msg_len);
if (msg_buf) {
@@ -451,8 +450,8 @@ struct data_packet mp_create_packet_from_bytes(
memcpy(msg_buf + 9, packet.contents.author, 32);
memcpy(msg_buf + 41, packet.contents.author_signing_pub, 32);
msg_buf[ 73 ] = packet.contents.recipient_count;
- memcpy(msg_buf + 74, packet.contents.recipients, 32 * MAX_RECIPIENTS);
- memcpy(msg_buf + 74 + 32 * MAX_RECIPIENTS, packet.contents.data, 65536);
+ memcpy(msg_buf + 74, packet.contents.recipients, 64 * MAX_RECIPIENTS);
+ memcpy(msg_buf + 74 + 64 * MAX_RECIPIENTS, packet.contents.data, 65536);
crypto_sign_detached(
packet.contents.signature, NULL, msg_buf, msg_len, author_keys.signing_priv);
free(msg_buf);
@@ -464,7 +463,7 @@ struct data_packet mp_create_packet_from_bytes(
mp_client_error_t mp_create_packet_from_file(
const char *filename,
byte recipient_count,
- hash *recipients,
+ recipient *recipients,
keypair author_keys,
struct data_packet *out_packet) {
FILE *file = fopen(filename, "rb");
@@ -509,9 +508,9 @@ struct data_packet mp_run_pow(struct data_packet packet, byte leading_zeros) {
memcpy(contents_buffer + 9, packet.contents.author, 32);
memcpy(contents_buffer + 41, packet.contents.author_signing_pub, 32);
contents_buffer[ 73 ] = packet.contents.recipient_count;
- memcpy(contents_buffer + 74, packet.contents.recipients, 32 * MAX_RECIPIENTS);
- memcpy(contents_buffer + 74 + 32 * MAX_RECIPIENTS, packet.contents.data, 65536);
- memcpy(contents_buffer + 74 + 32 * MAX_RECIPIENTS + 65536, packet.contents.signature, 64);
+ memcpy(contents_buffer + 74, packet.contents.recipients, 64 * MAX_RECIPIENTS);
+ memcpy(contents_buffer + 74 + 64 * MAX_RECIPIENTS, packet.contents.data, 65536);
+ memcpy(contents_buffer + 74 + 64 * MAX_RECIPIENTS + 65536, packet.contents.signature, 64);
packet.nonce = 0;
while (true) {
diff --git a/client/client.h b/client/client.h
index ee94d21..a2a6a28 100644
--- a/client/client.h
+++ b/client/client.h
@@ -8,6 +8,7 @@ typedef uint8_t byte;
typedef byte hash[ 32 ];
typedef byte public_key[ 32 ];
typedef byte private_key[ 32 ];
+typedef byte recipient[ 64 ];
typedef byte signature[ 64 ];
typedef byte ipv4[ 4 ];
typedef byte ipv6[ 16 ];
@@ -48,7 +49,7 @@ struct data_packet {
public_key author;
public_key author_signing_pub;
uint8_t recipient_count;
- public_key recipients[ 32 ];
+ recipient recipients[ 32 ];
byte data[ 65536 ];
signature signature;
} contents;
@@ -165,7 +166,7 @@ struct data_packet mp_create_packet_from_bytes(
const byte* input,
size_t input_len,
byte recipient_count,
- hash* recipients,
+ recipient* recipients,
keypair author_keys);
/**
@@ -180,7 +181,7 @@ struct data_packet mp_create_packet_from_bytes(
mp_client_error_t mp_create_packet_from_file(
const char* filename,
byte recipient_count,
- hash* recipients,
+ recipient* recipients,
keypair author_keys,
struct data_packet* out_packet);
diff --git a/src/common.c b/src/common.c
index 74515c1..0cc0240 100644
--- a/src/common.c
+++ b/src/common.c
@@ -21,6 +21,7 @@ typedef byte hash[ 32 ];
typedef byte public_key[ 32 ];
typedef byte private_key[ 32 ];
typedef byte signature[ 64 ];
+typedef byte recipient[ 64 ];
const uint16_t default_port = 8040;
@@ -146,7 +147,7 @@ struct data_packet {
public_key author; // message author
public_key author_signing_pub; // message signing pubkey
uint8_t recipient_count; // number of recipients. leave as 0 for public.
- public_key recipients[ 32 ]; // up to 32 recipients for packet
+ recipient recipients[ 32 ]; // up to 32 recipients for packet
byte data[ 65536 ]; // packet data
signature signature; // data signature
} contents;
@@ -181,7 +182,7 @@ static inline void write_u16_le(byte *b, uint16_t v) {
b[ 1 ] = (v >> 8) & 0xFF;
}
-const size_t CONTENTS_SIZE = 1 + 8 + 32 + 32 + 1 + (32 * MAX_RECIPIENTS) + 65536 + 64;
+const size_t CONTENTS_SIZE = 1 + 8 + 32 + 32 + 1 + (64 * MAX_RECIPIENTS) + 65536 + 64;
const size_t PACKET_SIZE = 4 + 32 + (CONTENTS_SIZE);
struct relay_neighbor s2relay_neighbor(size_t len, byte *stream, bool *success) {
@@ -251,7 +252,7 @@ struct relay_info s2relay_info(size_t len, byte *stream, bool *success) {
*success = false;
return (struct relay_info) { 0 };
}
- off += 1 + 1 + 1 + 4 + 16;
+ off += 1 + 1 + 1 + 4 + 16 + 2;
}
*success = true;
@@ -318,8 +319,8 @@ struct data_packet s2data_packet(size_t len, byte *stream, bool *success) {
off += 32;
out.contents.recipient_count = stream[ off++ ];
- memcpy(out.contents.recipients, stream + off, 32 * MAX_RECIPIENTS);
- off += 32 * MAX_RECIPIENTS;
+ memcpy(out.contents.recipients, stream + off, 64 * MAX_RECIPIENTS);
+ off += 64 * MAX_RECIPIENTS;
memcpy(out.contents.data, stream + off, 65536);
off += 65536;
@@ -355,8 +356,8 @@ bool data_packet2s(struct data_packet data, byte *stream) {
off += 32;
stream[ off++ ] = data.contents.recipient_count;
- memcpy(stream + off, data.contents.recipients, 32 * MAX_RECIPIENTS);
- off += 32 * MAX_RECIPIENTS;
+ memcpy(stream + off, data.contents.recipients, 64 * MAX_RECIPIENTS);
+ off += 64 * MAX_RECIPIENTS;
memcpy(stream + off, data.contents.data, 65536);
off += 65536;
diff --git a/src/external.h b/src/external.h
index e145f91..13f65dd 100644
--- a/src/external.h
+++ b/src/external.h
@@ -14,32 +14,53 @@ typedef byte hash[ 32 ];
typedef byte public_key[ 32 ];
typedef byte private_key[ 32 ];
typedef byte signature[ 64 ];
+typedef byte recipient[ 64 ];
const uint16_t default_port = 8040;
enum client_input {
// ask server for its information (responds with audit_response)
- audit_server = 0x9a,
+ audit_server = 0x10,
// ask server for a random set of neighbors
// (input uint8_t neighbor_count, responds with neighbors_info)
- get_neighbors = 0x20,
+ get_neighbors = 0x11,
// monitor incoming packets
// (input struct firehose_request, responds with firehose_reply)
- firehose = 0xf1,
+ firehose = 0x12,
// give a packet to the relay
// (input struct data_packet, responds with push_packet_result)
- push_packet = 0x88,
+ push_packet = 0x13,
// get a packet from the server
// (input hash, responds with get_packet_result)
- get_packet = 0x87,
+ get_packet = 0x14,
// register a new neighbor relay to this server
// (input struct relay_neighbor, responds with register_neighbor_result)
- register_neighbor = 0x73,
+ register_neighbor = 0x15,
+
+ // query packets for a specific author
+ // note: to prevent DoS, you must provide a signature by the requested author to be approved.
+ // the signature needs to be from a struct shaped `public_key + pub_sign_key + u16 count + u64
+ // offset`.
+ // server must verify the signing key is of the author's pubkey and signing key by looking at
+ // the packet's metadata.
+ // (input public_key, input pub_sign_key, signature, u16 count, u64 offset)
+ // (responds with queried_author_packets)
+ query_packets = 0x16,
+
+ // query packets for a specific recipient
+ // note: to prevent DoS, you must provide a signature by the requested author to be approved.
+ // the signature needs to be from a struct shaped `public_key + pub_sign_key + u16 count + u64
+ // offset`.
+ // server must verify the signing key is of the recipient's pubkey and signing key by looking at
+ // the packet's metadata.
+ // (input public_key, input pub_sign_key, signature, u16 count, u64 offset)
+ // (responds with queried_author_packets)
+ query_by_recipient = 0x17,
};
enum server_reply {
@@ -47,17 +68,21 @@ enum server_reply {
error = 0x1,
// type `struct relay_info`
- audit_response = 0xaf,
+ audit_response = 0x18,
// type `struct relay_neighbor[ neighbor_count ]`
- neighbors_info = 0x43,
+ neighbors_info = 0x19,
// type `uint64_t new_offset, struct data_packet[ count ]`
- firehose_reply = 0x6c,
+ firehose_reply = 0x1a,
// type `bool result_code`
- push_packet_result = 0x4a,
+ push_packet_result = 0x1b,
// type `struct data_packet`
- get_packet_result = 0x42,
+ get_packet_result = 0x1c,
// type `bool result_code`
- register_neighbor_result = 0x6e,
+ register_neighbor_result = 0x1d,
+ // type `u16 count, u64 new_offset, struct data_packet[ count ]`
+ queried_author_packets = 0x1e,
+ // type `u16 count, u64 new_offset, struct data_packet[ count ]`
+ queried_recipient_packets = 0x1f,
};
typedef uint8_t get_neighbors_request;
@@ -114,11 +139,11 @@ struct data_packet {
public_key author; // message author
public_key author_signing_pub; // message signing pubkey
uint8_t recipient_count; // number of recipients. leave as 0 for public.
- public_key recipients[ 32 ]; // up to 32 recipients for packet
+ recipient recipients[ 32 ]; // up to 32 recipients for packet
byte data[ 65536 ]; // packet data
signature signature; // data signature
} contents;
};
-const size_t CONTENTS_SIZE = 1 + 8 + 32 + 32 + 1 + (32 * MAX_RECIPIENTS) + 65536 + 64;
+const size_t CONTENTS_SIZE = 1 + 8 + 32 + 32 + 1 + (64 * MAX_RECIPIENTS) + 65536 + 64;
const size_t PACKET_SIZE = 4 + 32 + (CONTENTS_SIZE); \ No newline at end of file
diff --git a/src/packet_storage.c b/src/packet_storage.c
index 569eed4..39cff5c 100644
--- a/src/packet_storage.c
+++ b/src/packet_storage.c
@@ -48,11 +48,11 @@ struct author_entry {
} *author_storage;
struct recipient_entry {
- public_key recipient;
- uint64_t packet_head;
- uint64_t next;
- uint64_t prev;
- bool is_full;
+ recipient recipient;
+ uint64_t packet_head;
+ uint64_t next;
+ uint64_t prev;
+ bool is_full;
} *recipient_storage;
pthread_mutex_t author_storage_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -154,12 +154,12 @@ void save_author_packet_hash(const public_key author, const hash packet_hash) {
fclose(f);
}
-void save_recipient_packet_hash(const public_key recipient, const hash packet_hash) {
+void save_recipient_packet_hash(const recipient recipient, const hash packet_hash) {
const char *dir = "packets_by_recipient";
mkdir(dir, 0755);
- char recipient_hex[ 65 ];
- sprintf(recipient_hex, hash_fmt, hash_ref(recipient));
+ char recipient_hex[ 129 ];
+ sprintf(recipient_hex, hash_fmt hash_fmt, hash_ref(recipient), hash_ref((recipient + 32)));
char filename[ 256 ];
snprintf(filename, sizeof(filename), "%s/%s.list", dir, recipient_hex);
@@ -227,7 +227,7 @@ uint64_t get_author_entry(const public_key auth_key, bool create) {
return invalid_index;
}
-uint64_t get_recipient_entry(const public_key recip_key, bool create) {
+uint64_t get_recipient_entry(const recipient recip_key, bool create) {
uint64_t hash_val;
memcpy(&hash_val, recip_key, sizeof(uint64_t));
uint64_t start_index = hash_val % max_recipients;
@@ -237,7 +237,7 @@ uint64_t get_recipient_entry(const public_key recip_key, bool create) {
struct recipient_entry *current = &recipient_storage[ cur_index ];
while (true) {
- if (current->is_full && memcmp(current->recipient, recip_key, 32) == 0) {
+ if (current->is_full && memcmp(current->recipient, recip_key, 64) == 0) {
pthread_mutex_unlock(&recipient_storage_mutex);
return cur_index;
}
@@ -252,7 +252,7 @@ uint64_t get_recipient_entry(const public_key recip_key, bool create) {
}
if (!current->is_full) {
- memcpy(current->recipient, recip_key, 32);
+ memcpy(current->recipient, recip_key, 64);
current->packet_head = invalid_index;
current->is_full = true;
current->next = invalid_index;
@@ -266,7 +266,7 @@ uint64_t get_recipient_entry(const public_key recip_key, bool create) {
while (probes < max_recipients) {
struct recipient_entry *empty = &recipient_storage[ lp_idx ];
if (!empty->is_full) {
- memcpy(empty->recipient, recip_key, 32);
+ memcpy(empty->recipient, recip_key, 64);
empty->packet_head = invalid_index;
empty->is_full = true;
empty->next = invalid_index;
@@ -343,22 +343,32 @@ uint64_t set_data_packet(struct data_packet *new_packet) {
struct data_packet_entry *current_entry = &packet_index[ cur_index ];
while (true) {
- if (current_entry->is_full
- && memcmp(
- ((struct data_packet *) current_entry->compressed_payload)->hash,
- new_packet->hash,
- sizeof(hash))
- == 0) {
- arena_free(current_entry->compressed_payload);
- current_entry->compressed_payload = compressed_payload;
- current_entry->compressed_size = compressed_len;
- pthread_mutex_unlock(&packet_storage_mutex);
- save_author_packet_hash(new_packet->contents.author, new_packet->hash);
- for (uint8_t i = 0; i < new_packet->contents.recipient_count; i++) {
- save_recipient_packet_hash(new_packet->contents.recipients[ i ], new_packet->hash);
+ if (current_entry->is_full) {
+ static __thread byte decompressed[ sizeof(struct data_packet) ];
+ uLongf decompressed_len = sizeof(struct data_packet);
+ if (uncompress(
+ decompressed,
+ &decompressed_len,
+ current_entry->compressed_payload,
+ current_entry->compressed_size)
+ == Z_OK) {
+ if (memcmp(
+ ((struct data_packet *) decompressed)->hash, new_packet->hash, sizeof(hash))
+ == 0) {
+ arena_free(current_entry->compressed_payload);
+ current_entry->compressed_payload = compressed_payload;
+ current_entry->compressed_size = compressed_len;
+ pthread_mutex_unlock(&packet_storage_mutex);
+ save_author_packet_hash(new_packet->contents.author, new_packet->hash);
+ for (uint8_t i = 0; i < new_packet->contents.recipient_count; i++) {
+ save_recipient_packet_hash(
+ new_packet->contents.recipients[ i ], new_packet->hash);
+ }
+ return cur_index;
+ }
}
- return cur_index;
}
+
if (current_entry->next == invalid_index) break;
cur_index = current_entry->next;
current_entry = &packet_index[ cur_index ];
@@ -575,11 +585,11 @@ bool _delete_at_index(uint64_t index) {
for (uint8_t i = 0;
i < ((struct data_packet *) current_entry->compressed_payload)->contents.recipient_count;
i++) {
- public_key recip_key;
+ recipient recip_key;
memcpy(
recip_key,
((struct data_packet *) current_entry->compressed_payload)->contents.recipients[ i ],
- 32);
+ 64);
uint64_t recip_idx = get_recipient_entry(recip_key, false);
if (recip_idx != invalid_index) {
if (recipient_storage[ recip_idx ].packet_head == index) {
@@ -732,7 +742,7 @@ uint16_t get_packets_for_author(
}
uint16_t get_packets_for_recipient(
- const public_key recipient,
+ const recipient recipient,
uint64_t offset,
uint16_t max_count,
struct data_packet *out_packets,
@@ -776,8 +786,8 @@ uint16_t get_packets_for_recipient(
}
pthread_mutex_unlock(&packet_storage_mutex);
- char recipient_hex[ 65 ];
- sprintf(recipient_hex, hash_fmt, hash_ref(recipient));
+ char recipient_hex[ 129 ];
+ sprintf(recipient_hex, hash_fmt hash_fmt, hash_ref(recipient), hash_ref((recipient + 32)));
char filename[ 256 ];
snprintf(filename, sizeof(filename), "packets_by_recipient/%s.list", recipient_hex);
diff --git a/src/server.c b/src/server.c
index 3f1a9ee..a676066 100644
--- a/src/server.c
+++ b/src/server.c
@@ -351,10 +351,10 @@ void paste_server(
memcpy(contents_buffer + 9, packet.contents.author, 32);
memcpy(contents_buffer + 41, packet.contents.author_signing_pub, 32);
contents_buffer[ 73 ] = packet.contents.recipient_count;
- memcpy(contents_buffer + 74, packet.contents.recipients, 32 * MAX_RECIPIENTS);
- memcpy(contents_buffer + 74 + 32 * MAX_RECIPIENTS, packet.contents.data, 65536);
+ memcpy(contents_buffer + 74, packet.contents.recipients, 64 * MAX_RECIPIENTS);
+ memcpy(contents_buffer + 74 + 64 * MAX_RECIPIENTS, packet.contents.data, 65536);
memcpy(
- contents_buffer + 74 + 32 * MAX_RECIPIENTS + 65536, packet.contents.signature, 64);
+ contents_buffer + 74 + 64 * MAX_RECIPIENTS + 65536, packet.contents.signature, 64);
struct sha256 calculated_hash_struct = sha256_hash(hash_input_buffer, hash_input_len);
if (memcmp(calculated_hash_struct.hash, packet.hash, sizeof(hash)) != 0) {