diff options
| author | 2025-09-16 11:22:51 +0330 | |
|---|---|---|
| committer | 2025-09-16 11:22:51 +0330 | |
| commit | 6bc2bf4e1bdb0d3a61c936c99e1ba671c54222b8 (patch) | |
| tree | 285e95a2052fe9e4a74c9ededb855a46842747ca /src/server.c | |
| parent | add new opcode + firehose change (diff) | |
compressino + fixed logic
Diffstat (limited to 'src/server.c')
| -rw-r--r-- | src/server.c | 108 |
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); |
