diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common.c | 15 | ||||
| -rw-r--r-- | src/external.h | 53 | ||||
| -rw-r--r-- | src/packet_storage.c | 72 | ||||
| -rw-r--r-- | src/server.c | 6 |
4 files changed, 91 insertions, 55 deletions
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) { |
