diff options
| -rw-r--r-- | src/packet_storage.c | 34 | ||||
| -rw-r--r-- | src/server.c | 83 |
2 files changed, 94 insertions, 23 deletions
diff --git a/src/packet_storage.c b/src/packet_storage.c index 39cff5c..bb8cdcd 100644 --- a/src/packet_storage.c +++ b/src/packet_storage.c @@ -343,30 +343,18 @@ 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) { - 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; - } + if (current_entry->is_full && + current_entry->compressed_size == compressed_len && + memcmp(current_entry->compressed_payload, compressed_payload, compressed_len) == 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; } if (current_entry->next == invalid_index) break; diff --git a/src/server.c b/src/server.c index b3c5590..cc1f45d 100644 --- a/src/server.c +++ b/src/server.c @@ -637,6 +637,89 @@ void paste_server( return; } break; + case query_by_recipient: { + if (in_len < 1 + 32 + 32 + 64 + 2 + 8) { + log(_error, "query_by_recipient: input too short, got %zu bytes", in_len); + byte resp = error; + *out = malloc(1); + if (*out) { + (*out)[ 0 ] = resp; + *out_len = 1; + } else { + *out_len = 0; + } + break; + } + public_key author; + public_key signing_pub; + signature sig; + uint16_t count; + uint64_t offset; + size_t off = 1; + memcpy(author, in + off, 32); + off += 32; + memcpy(signing_pub, in + off, 32); + off += 32; + memcpy(sig, in + off, 64); + off += 64; + count = read_u16_le(in + off); + off += 2; + offset = read_u64_le(in + off); + + byte msg[ 32 + 32 + 2 + 8 ]; + memcpy(msg, author, 32); + memcpy(msg + 32, signing_pub, 32); + write_u16_le(msg + 64, count); + write_u64_le(msg + 66, offset); + + if (crypto_sign_verify_detached(sig, msg, sizeof(msg), signing_pub) != 0) { + log(_error, "query_by_recipient: signature verification failed for author"); + byte resp = error; + *out = malloc(1); + if (*out) { + (*out)[ 0 ] = resp; + *out_len = 1; + } else { + *out_len = 0; + } + break; + } + + log(_info, + "query_by_recipient: fetching %u packets for recipient, offset %lu", + count, + offset); + struct data_packet packets[ 256 ]; + uint64_t new_offset; + uint16_t collected + = get_packets_for_recipient(author, offset, count, packets, &new_offset); + + *out_len = 1 + 2 + 8 + collected * PACKET_SIZE; + *out = malloc(*out_len); + if (!*out) { + log(_error, + "query_by_recipient: failed to allocate %zu bytes for response", + *out_len); + *out_len = 0; + break; + } + off = 0; + (*out)[ off++ ] = queried_recipient_packets; + write_u16_le(*out + off, collected); + off += 2; + write_u64_le(*out + off, new_offset); + off += 8; + for (uint16_t i = 0; i < collected; i++) { + data_packet2s(packets[ i ], *out + off); + off += PACKET_SIZE; + } + log(_info, + "query_by_recipient: returned %u packets, new offset %lu", + collected, + new_offset); + break; + } + default: { log(_info, "<%.*s> request type: invalid method", (int) ip_size, ip_addr); |
