summaryrefslogtreecommitdiff
path: root/src/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.c')
-rw-r--r--src/server.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/server.c b/src/server.c
index 3140788..630df87 100644
--- a/src/server.c
+++ b/src/server.c
@@ -707,6 +707,114 @@ void paste_server(
break;
}
+ case query_by_id_hash: {
+ if (in_len < 1 + 4 + 32) {
+ byte* output_data = calloc(1 + 17, sizeof(byte));
+ if (!output_data) {
+ *out = NULL;
+ *out_len = 0;
+ break;
+ }
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "input too small", 17);
+ reply(18, output_data);
+ break;
+ }
+
+ uint64_t __fetch_index = read_u64_le(in + 1);
+ hash packet_hash;
+ bool success;
+ s2hash(32, in + 1 + 4, &success, packet_hash);
+
+ log(_info,
+ "<%.*s> request type: get packet with hash " hash_fmt " id %li",
+ (int) ip_size,
+ ip_addr,
+ hash_ref(packet_hash),
+ __fetch_index);
+
+ if (!success) {
+ byte* output_data = calloc(1 + 12, sizeof(byte));
+ if (!output_data) {
+ *out = NULL;
+ *out_len = 0;
+ break;
+ }
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "invalid hash", 12);
+ reply(13, output_data);
+ break;
+ }
+
+ struct data_packet_entry* entry
+ = __fetch_index >= max_storage ? NULL : &packet_index[ __fetch_index ];
+ if (entry == NULL || !entry->is_full) {
+ byte* output_data = calloc(1 + 14, sizeof(byte));
+ if (!output_data) {
+ *out = NULL;
+ *out_len = 0;
+ return;
+ }
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "packet not found", 14);
+ reply(15, output_data);
+ break;
+ }
+
+ uLongf uncompressed_size = sizeof(struct data_packet);
+ struct data_packet* uncompressed_data = malloc(uncompressed_size);
+
+ int ret = uncompress(
+ (byte*) uncompressed_data,
+ &uncompressed_size,
+ entry->compressed_payload,
+ entry->compressed_size);
+
+ if (ret != Z_OK) {
+ log(_error, "decompression failed with error code: %d", ret);
+ byte* output_data = calloc(1 + 20, sizeof(byte));
+ if (output_data) {
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "decompression failed", 20);
+ reply(21, output_data);
+ }
+ free(uncompressed_data);
+ break;
+ }
+
+ if (memcmp(uncompressed_data->hash, packet_hash, sizeof(hash)) != 0) {
+ log(_error, "packet hash does not match");
+ byte* output_data = calloc(1 + 17, sizeof(byte));
+ if (output_data) {
+ output_data[ 0 ] = error;
+ memcpy(output_data + 1, "non matching hash", 17);
+ reply(18, output_data);
+ }
+ free(uncompressed_data);
+ break;
+ }
+
+ size_t output_len = 1 + uncompressed_size;
+ byte* output_data = calloc(output_len, sizeof(byte));
+ if (!output_data) {
+ free(uncompressed_data);
+ byte* err = calloc(1 + 14, sizeof(byte));
+ if (err) {
+ err[ 0 ] = error;
+ memcpy(err + 1, "server OOM", 10);
+ reply(11, err);
+ }
+ break;
+ }
+
+ output_data[ 0 ] = get_packet_result;
+ memcpy(output_data + 1, uncompressed_data, uncompressed_size);
+ free(uncompressed_data);
+
+ reply(output_len, output_data);
+ break;
+ }
+
default: {
log(_info, "<%.*s> request type: invalid method", (int) ip_size, ip_addr);