diff --git a/include/tcp-chat.h b/include/tcp-chat.h index 9a1ed45..cd608e3 100644 --- a/include/tcp-chat.h +++ b/include/tcp-chat.h @@ -1,5 +1,7 @@ #pragma once #include "tlibc/errors.h" +#include "tlibc/time.h" +#include "tlibc/magic.h" /// requires tlibc and tlibtoml init Result(void) TcpChat_init(); @@ -63,6 +65,7 @@ typedef void (*LogFunction_t)(void* logger, cstr context, LogSeverity severity, #define logWarn(format, ...) log(LogSeverity_Warn, format ,##__VA_ARGS__) #define logError(format, ...) log(LogSeverity_Error, format ,##__VA_ARGS__) + ////////////////////////////////////////////////////////////////////////////// // // // Server // @@ -82,6 +85,7 @@ void Server_free(Server* server); Result(void) Server_run(Server* server); + ////////////////////////////////////////////////////////////////////////////// // // // Client // @@ -117,3 +121,15 @@ Result(void) Client_register(Client* self, i64* out_user_id); /// Authorize on connected server Result(void) Client_login(Client* self, i64* out_user_id, i64* out_landing_channel_id); + +/// @param out_timestamp timestamp received from server +/// @return message id received from server +Result(i64) Client_sendMessage(Client* self, i64 channel_id, Array(u8) content, DateTime* out_timestamp); + +/// Receive a bunch of messages from the server to a client internal buffer +/// @return number of messages received +Result(u32) Client_receiveMessageBlock(Client* self, i64 channel_id, i64 first_message_id, u32 messages_count); + +/// Read message saved in client internal buffer. +/// @return number of bytes written in dst_content +Result(u32) Client_popMessage(Client* self, Array(u8) dst_content, i64* message_id, i64* sender_id, DateTime* timestamp_utc); diff --git a/src/client/ServerConnection.c b/src/client/ServerConnection.c index 52fa3b9..904630a 100644 --- a/src/client/ServerConnection.c +++ b/src/client/ServerConnection.c @@ -8,6 +8,7 @@ void ServerConnection_close(ServerConnection* self){ EncryptedSocketTCP_destroy(&self->sock); Array_u8_destroy(&self->token); Array_u8_destroy(&self->session_key); + MessageBlock_destroy(&self->received_message_block); free(self); } @@ -73,6 +74,8 @@ Result(ServerConnection*) ServerConnection_open(Client* client, cstr server_addr PacketType_ServerHandshake)); conn->session_id = server_handshake.session_id; + MessageBlock_alloc(&conn->received_message_block); + success = true; Return RESULT_VALUE(p, conn); } diff --git a/src/client/client.c b/src/client/client.c index e17615e..33b116d 100644 --- a/src/client/client.c +++ b/src/client/client.c @@ -80,7 +80,6 @@ Result(void) Client_register(Client* self, i64* out_user_id){ PacketHeader req_head, res_head; RegisterRequest req; RegisterResponse res; - // TODO: hash token with server public key try_void(RegisterRequest_tryConstruct(&req, &req_head, self->username, self->conn->token)); try_void(sendRequest(&self->conn->sock, &req_head, &req)); try_void(recvResponse(&self->conn->sock, &res_head, &res, PacketType_RegisterResponse)); @@ -98,7 +97,6 @@ Result(void) Client_login(Client* self, i64* out_user_id, i64* out_landing_chann PacketHeader req_head, res_head; LoginRequest req; LoginResponse res; - // TODO: hash token with server public key try_void(LoginRequest_tryConstruct(&req, &req_head, self->username, self->conn->token)); try_void(sendRequest(&self->conn->sock, &req_head, &req)); try_void(recvResponse(&self->conn->sock, &res_head, &res, PacketType_LoginResponse)); @@ -108,3 +106,71 @@ Result(void) Client_login(Client* self, i64* out_user_id, i64* out_landing_chann Return RESULT_VOID; } + +Result(i64) Client_sendMessage(Client* self, i64 channel_id, Array(u8) content, DateTime* out_timestamp){ + Deferral(1); + try_assert(self != NULL); + try_assert(self->conn != NULL && "didn't connect to a server yet"); + try_assert(content.len >= MESSAGE_SIZE_MIN && content.len <= MESSAGE_SIZE_MAX); + + PacketHeader req_head, res_head; + SendMessageRequest req; + SendMessageResponse res; + SendMessageRequest_construct(&req, &req_head, channel_id, content.len); + try_void(sendRequest(&self->conn->sock, &req_head, &req)); + try_void(recvResponse(&self->conn->sock, &res_head, &res, PacketType_SendMessageResponse)); + *out_timestamp = res.timestamp; + + Return RESULT_VALUE(i, res.message_id); +} + +Result(u32) Client_receiveMessageBlock(Client* self, i64 channel_id, i64 first_message_id, u32 messages_count){ + Deferral(1); + try_assert(self != NULL); + try_assert(self->conn != NULL && "didn't connect to a server yet"); + + PacketHeader req_head, res_head; + GetMessageBlockRequest req; + GetMessageBlockResponse res; + GetMessageBlockRequest_construct(&req, &req_head, channel_id, first_message_id, messages_count); + try_void(sendRequest(&self->conn->sock, &req_head, &req)); + try_void(recvResponse(&self->conn->sock, &res_head, &res, PacketType_GetMessageBlockResponse)); + self->conn->received_message_block.messages_count = res.messages_count; + self->conn->received_message_block.datum.len = res.data_size; + try_void( + EncryptedSocketTCP_recv( + &self->conn->sock, + self->conn->received_message_block.datum, + SocketRecvFlag_WholeBuffer + ) + ); + + Return RESULT_VALUE(u, res.messages_count); +} + +Result(u32) Client_popMessage(Client* self, Array(u8) dst_content, + i64* message_id, i64* sender_id, DateTime* timestamp_utc) +{ + Deferral(1); + try_assert(self != NULL); + try_assert(self->conn != NULL && "didn't connect to a server yet"); + try_assert(dst_content.len >= MESSAGE_SIZE_MAX); + + MessageMeta msg_meta = {0}; + try(bool read_success, u, + MessageBlock_readMessage( + &self->conn->received_message_block, + &msg_meta, + dst_content + ) + ); + if(!read_success){ + Return RESULT_VALUE(u, 0); + } + + *message_id = msg_meta.id; + *sender_id = msg_meta.sender_id; + *timestamp_utc = msg_meta.timestamp; + + Return RESULT_VALUE(u, msg_meta.data_size); +} diff --git a/src/client/client_internal.h b/src/client/client_internal.h index b8a4554..41387d7 100644 --- a/src/client/client_internal.h +++ b/src/client/client_internal.h @@ -3,6 +3,7 @@ #include "cryptography/AES.h" #include "cryptography/RSA.h" #include "network/encrypted_sockets.h" +#include "network/tcp-chat-protocol/v1.h" typedef struct ServerConnection ServerConnection; @@ -12,7 +13,6 @@ typedef struct Client { ServerConnection* conn; } Client; - typedef struct ServerConnection { Client* client; EndpointIPv4 server_end; @@ -23,6 +23,7 @@ typedef struct ServerConnection { EncryptedSocketTCP sock; i64 session_id; i64 user_id; + MessageBlock received_message_block; } ServerConnection; /// @param server_addr_cstr diff --git a/src/cryptography/RSA.c b/src/cryptography/RSA.c index e7af538..d9667d6 100644 --- a/src/cryptography/RSA.c +++ b/src/cryptography/RSA.c @@ -1,7 +1,5 @@ #include "RSA.h" #include -#include "bearssl_x509.h" -#include "bearssl_pem.h" #include "tlibc/base64.h" // https://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537 diff --git a/src/network/tcp-chat-protocol/v1.c b/src/network/tcp-chat-protocol/v1.c index bba1c49..1621244 100644 --- a/src/network/tcp-chat-protocol/v1.c +++ b/src/network/tcp-chat-protocol/v1.c @@ -142,62 +142,67 @@ void RegisterResponse_construct(RegisterResponse *ptr, PacketHeader* header, ptr->user_id = user_id; } -Result(u32) MessageBlock_writeMessage( - MessageMeta* msg, Array(u8) msg_content, - MessageBlockMeta* block_meta, Array(u8)* block_free_part) +Result(bool) MessageBlock_writeMessage(MessageBlock* block, + const MessageMeta* msg_meta, const Array(u8) msg_content) { Deferral(1); - try_assert(msg->data_size >= MESSAGE_SIZE_MIN && msg->data_size <= MESSAGE_SIZE_MAX); - try_assert(msg->data_size <= msg_content.len); - u32 offset_increment = sizeof(MessageMeta) + msg->data_size; - if(block_free_part->len < offset_increment){ - Return RESULT_VALUE(u, 0); + // check msg_meta + try_assert(msg_meta->magic.n == MESSAGE_MAGIC.n); + try_assert(msg_meta->data_size >= MESSAGE_SIZE_MIN && msg_meta->data_size <= MESSAGE_SIZE_MAX); + try_assert(msg_meta->data_size <= msg_content.len); + try_assert(msg_meta->id > 0); + try_assert(msg_meta->sender_id > 0); + try_assert(msg_meta->timestamp.d.year > 2024); + // check block->datum.len + if(block->datum.len < block->offset + sizeof(MessageMeta) + msg_meta->data_size){ + Return RESULT_VALUE(u, false); } - memcpy(block_free_part->data, msg, sizeof(MessageMeta)); - block_free_part->data += sizeof(MessageMeta); - block_free_part->len -= sizeof(MessageMeta); + // write msg_meta + memcpy(block->datum.data + block->offset, msg_meta, sizeof(MessageMeta)); + block->offset += sizeof(MessageMeta); - memcpy(block_free_part->data, msg_content.data, msg->data_size); - block_free_part->data += msg->data_size; - block_free_part->len -= msg->data_size; - - if(block_meta->message_count == 0) - block_meta->first_message_id = msg->id; - block_meta->message_count++; - block_meta->data_size += offset_increment; + // write msg_content + memcpy(block->datum.data + block->offset, msg_content.data, msg_meta->data_size); + block->offset += msg_meta->data_size; - Return RESULT_VALUE(u, offset_increment); + block->messages_count++; + Return RESULT_VALUE(u, true); } -Result(u32) MessageBlock_readMessage( - Array(u8)* block_unread_part, - MessageMeta* msg, Array(u8) msg_content) +Result(bool) MessageBlock_readMessage(MessageBlock* block, + MessageMeta* msg_meta, Array(u8) msg_content) { Deferral(1); - try_assert(block_unread_part->len >= sizeof(MessageMeta) + MESSAGE_SIZE_MIN); - try_assert(msg_content.len >= MESSAGE_SIZE_MIN && msg_content.len <= MESSAGE_SIZE_MAX); - - memcpy(msg, block_unread_part->data, sizeof(MessageMeta)); - block_unread_part->data += sizeof(MessageMeta); - block_unread_part->len -= sizeof(MessageMeta); - if(msg->magic.n != MESSAGE_MAGIC.n){ - Return RESULT_VALUE(u, 0); + // check block + if(block->messages_count == 0){ + Return RESULT_VALUE(u, false); } - try_assert(block_unread_part->len >= msg->data_size); - try_assert(msg->data_size >= MESSAGE_SIZE_MIN && msg->data_size <= MESSAGE_SIZE_MAX); - try_assert(msg->id > 0); - try_assert(msg->sender_id > 0); - try_assert(msg->timestamp.d.year > 2024); + try_assert(block->datum.len >= block->offset + sizeof(MessageMeta) + MESSAGE_SIZE_MIN); + // check msg_content.len + try_assert(msg_content.len >= MESSAGE_SIZE_MAX); + + // read msg_meta + memcpy(msg_meta, block->datum.data + block->offset, sizeof(MessageMeta)); + block->offset += sizeof(MessageMeta); - memcpy(msg_content.data, block_unread_part->data, msg->data_size); - block_unread_part->data += msg->data_size; - block_unread_part->len -= msg->data_size; + // check msg_meta + try_assert(msg_meta->magic.n == MESSAGE_MAGIC.n); + try_assert(msg_meta->data_size >= MESSAGE_SIZE_MIN && msg_meta->data_size <= MESSAGE_SIZE_MAX); + try_assert(msg_meta->data_size <= msg_content.len); + try_assert(msg_meta->id > 0); + try_assert(msg_meta->sender_id > 0); + try_assert(msg_meta->timestamp.d.year > 2024); + try_assert(block->datum.len >= block->offset + msg_meta->data_size); - u32 offset_increment = sizeof(MessageMeta) + msg->data_size; - Return RESULT_VALUE(u, offset_increment); + // read msg_content + memcpy(msg_content.data, block->datum.data + block->offset, msg_meta->data_size); + block->offset += msg_meta->data_size; + + block->messages_count--; + Return RESULT_VALUE(u, true); } void SendMessageRequest_construct(SendMessageRequest *ptr, PacketHeader *header, @@ -219,19 +224,20 @@ void SendMessageResponse_construct(SendMessageResponse *ptr, PacketHeader *heade } void GetMessageBlockRequest_construct(GetMessageBlockRequest *ptr, PacketHeader *header, - i64 channel_id, i64 first_message_id, u32 message_count) + i64 channel_id, i64 first_message_id, u32 messages_count) { _PacketHeader_construct(GetMessageBlockRequest); zeroStruct(ptr); ptr->channel_id = channel_id; ptr->first_message_id = first_message_id; - ptr->message_count = message_count; + ptr->messages_count = messages_count; } void GetMessageBlockResponse_construct(GetMessageBlockResponse *ptr, PacketHeader *header, - MessageBlockMeta* block_meta) + u32 messages_count, u32 data_size) { _PacketHeader_construct(GetMessageBlockResponse); zeroStruct(ptr); - memcpy(&ptr->block_meta, block_meta, sizeof(MessageBlockMeta)); + ptr->messages_count = messages_count; + ptr->data_size = data_size; } diff --git a/src/network/tcp-chat-protocol/v1.h b/src/network/tcp-chat-protocol/v1.h index ecc994f..9f62e66 100644 --- a/src/network/tcp-chat-protocol/v1.h +++ b/src/network/tcp-chat-protocol/v1.h @@ -129,30 +129,63 @@ typedef struct MessageMeta { i64 id; i64 sender_id; DateTime timestamp; /* UTC */ -} ALIGN_PACKET_STRUCT MessageMeta; +} ATTRIBUTE_ALIGNED(8) MessageMeta; -#define MESSAGE_MAGIC ((Magic32){ .bytes = { 'M', 's', 'g', 'S' } }) +#define MessageMeta_construct(DATA_SIZE, MESSAGE_ID, SENDER_ID, TIMESTAMP) ((MessageMeta){ \ + .magic = MESSAGE_MAGIC, \ + .data_size = DATA_SIZE, \ + .id = MESSAGE_ID, \ + .sender_id = SENDER_ID, \ + .timestamp = TIMESTAMP \ +}) -typedef struct MessageBlockMeta { - i64 first_message_id; - u32 message_count; - u32 data_size; -} ALIGN_PACKET_STRUCT MessageBlockMeta; +#define MESSAGE_MAGIC ((Magic32){ .bytes = { 'M', 's', 'g', '1' } }) -/// @brief write msg_meta and msg_meta->data_size bytes from msg_content to buffer -/// @param block_meta set to {0} if block is empty yet -/// @param block_free_part .data and .len are adjusted to point to free part -/// @return amount of bytes written to block, may be 0 if msg_meta and msg_content don't fit -Result(u32) MessageBlock_writeMessage( - MessageMeta* msg_meta, Array(u8) msg_content, - MessageBlockMeta* block_meta, Array(u8)* block_free_part); +typedef struct MessageBlock { + Array(u8) datum; // sequence(MessageMeta, byte[MessageMeta.data_size]) + u32 messages_count; + u32 offset; +} MessageBlock; -/// @brief read message meta and content from buffer -/// @param block_unread_part .data and .len are adjusted to point to unread part -/// @param msg_content .len must be >= MESSAGE_SIZE_MAX -/// @return amount of bytes read from block, may be 0 if it doesn't start with MESSAGE_MAGIC -Result(u32) MessageBlock_readMessage( - Array(u8)* block_unread_part, +static inline void MessageBlock_construct(MessageBlock* self, Array(u8) datum, u32 messages_count){ + self->datum = datum; + self->messages_count = messages_count; + self->offset = 0; +} + +static inline void MessageBlock_alloc(MessageBlock* self){ + self->datum = Array_u8_alloc(MESSAGE_BLOCK_COUNT_MAX * (sizeof(MessageMeta) + MESSAGE_SIZE_MAX)); + Array_u8_memset(&self->datum, 0); + self->messages_count = 0; + self->offset = 0; +} + +static inline void MessageBlock_reset(MessageBlock* self){ + Array_u8_memset(&self->datum, 0); + self->messages_count = 0; + self->offset = 0; +} + +static inline void MessageBlock_destroy(MessageBlock* self){ + if(!self) + return; + Array_u8_destroy(&self->datum); +} + +/// @brief write msg_meta and msg_meta->data_size bytes from msg_content to block and increase block.messages_count +/// @param block use MessageBlock_alloc() to create empty block +/// @param msg_meta use MessageMeta_construct() to create message metadata +/// @param msg_content array of size >= msg_meta.data_size +/// @return false if msg_meta and msg_content don't fit in block.datum +Result(bool) MessageBlock_writeMessage(MessageBlock* block, + const MessageMeta* msg_meta, const Array(u8) msg_content); + +/// @brief read msg_meta and msg_content from block and decrease block.messages_count +/// @param block a block with correct .datum and .messages_count +/// @param msg_meta out meta copied from block_data +/// @param msg_content out content copied from block_data. Array of size >= MESSAGE_SIZE_MAX +/// @return false if there are no messages to read (block.messages_count == 0) +Result(bool) MessageBlock_readMessage(MessageBlock* block, MessageMeta* msg_meta, Array(u8) msg_content); @@ -178,18 +211,19 @@ void SendMessageResponse_construct(SendMessageResponse* ptr, PacketHeader* heade typedef struct GetMessageBlockRequest { i64 channel_id; i64 first_message_id; - u32 message_count; + u32 messages_count; } ALIGN_PACKET_STRUCT GetMessageBlockRequest; void GetMessageBlockRequest_construct(GetMessageBlockRequest* ptr, PacketHeader* header, - i64 channel_id, i64 first_message_id, u32 message_count); + i64 channel_id, i64 first_message_id, u32 messages_count); typedef struct GetMessageBlockResponse { - MessageBlockMeta block_meta; + u32 messages_count; + u32 data_size; /* stream of size data_size : sequence (MessageMeta, byte[MessageMeta.data_size]) */ } ALIGN_PACKET_STRUCT GetMessageBlockResponse; void GetMessageBlockResponse_construct(GetMessageBlockResponse* ptr, PacketHeader* header, - MessageBlockMeta* block_meta); + u32 messages_count, u32 data_size); diff --git a/src/server/ClientConnection.c b/src/server/ClientConnection.c index 9f74731..e961a4c 100644 --- a/src/server/ClientConnection.c +++ b/src/server/ClientConnection.c @@ -5,7 +5,7 @@ void ClientConnection_close(ClientConnection* conn){ return; EncryptedSocketTCP_destroy(&conn->sock); Array_u8_destroy(&conn->session_key); - Array_u8_destroy(&conn->message_block); + MessageBlock_destroy(&conn->message_block); Array_u8_destroy(&conn->message_content); ServerQueries_free(conn->queries); tsqlite_connection_close(conn->db); @@ -26,7 +26,7 @@ Result(ClientConnection*) ClientConnection_accept(ConnectionHandlerArgs* args) conn->session_id = args->session_id; // buffers - conn->message_block = Array_u8_alloc(MESSAGE_BLOCK_COUNT_MAX * (sizeof(MessageMeta) + MESSAGE_SIZE_MAX)); + MessageBlock_alloc(&conn->message_block); conn->message_content = Array_u8_alloc(MESSAGE_SIZE_MAX); // database diff --git a/src/server/db/Channel.c b/src/server/db/Channel.c index 4a0ac2c..08d327e 100644 --- a/src/server/db/Channel.c +++ b/src/server/db/Channel.c @@ -63,14 +63,14 @@ Result(void) Channel_saveMessage(ServerQueries* q, Result(void) Channel_loadMessageBlock(ServerQueries* q, i64 channel_id, i64 first_message_id, u32 count, - MessageBlockMeta* block_meta, Array(u8) block_data) + MessageBlock* block) { Deferral(4); - try_assert(channel_id > 0); - try_assert(block_data.len >= count * (sizeof(MessageMeta) + MESSAGE_SIZE_MAX)); if(count == 0){ Return RESULT_VOID; } + try_assert(channel_id > 0); + try_assert(block->datum.len >= count * (sizeof(MessageMeta) + MESSAGE_SIZE_MAX)); tsqlite_statement* st = q->messages.get_block; Defer(tsqlite_statement_reset(st)); @@ -78,9 +78,7 @@ Result(void) Channel_loadMessageBlock(ServerQueries* q, try_void(tsqlite_statement_bind_i64(st, "$first_message_id", first_message_id)); try_void(tsqlite_statement_bind_i64(st, "$count", count)); - zeroStruct(block_meta); - MessageMeta msg_meta = {0}; - Array(u8) msg_content; + MessageBlock_reset(block); str tmp_str = str_null; while(true){ try(bool has_result, i, tsqlite_statement_step(st)); @@ -88,17 +86,24 @@ Result(void) Channel_loadMessageBlock(ServerQueries* q, break; // id - try(msg_meta.id, i, tsqlite_statement_getResult_i64(st)); + try(i64 message_id, i, tsqlite_statement_getResult_i64(st)); // sender_id - try(msg_meta.sender_id, i, tsqlite_statement_getResult_i64(st)); + try(i64 sender_id, i, tsqlite_statement_getResult_i64(st)); // content + Array(u8) msg_content; try_void(tsqlite_statement_getResult_blob(st, &msg_content)); // timestamp try_void(tsqlite_statement_getResult_str(st, &tmp_str)); - try_void(DateTime_parse(tmp_str.data, &msg_meta.timestamp)); + DateTime timestamp; + try_void(DateTime_parse(tmp_str.data, ×tamp)); - try(u32 write_n, u, MessageBlock_writeMessage(&msg_meta, msg_content, block_meta, &block_data)); - try_assert(write_n > 0); + MessageMeta msg_meta = MessageMeta_construct( + msg_content.len, + message_id, + sender_id, + timestamp); + try(bool write_success, u, MessageBlock_writeMessage(block, &msg_meta, msg_content)); + try_assert(write_success == true); } Return RESULT_VOID; diff --git a/src/server/db/server_db.h b/src/server/db/server_db.h index a6e5572..84979b4 100644 --- a/src/server/db/server_db.h +++ b/src/server/db/server_db.h @@ -22,12 +22,11 @@ Result(i64) Channel_saveMessage(ServerQueries* q, i64 channel_id, i64 sender_id, Array(u8) content, DateTime* out_timestamp_utc); -/// @brief try to find `count` messages starting from `first_message_id` -/// @param out_meta writes here information about found messages, .count can be 0 if no messages found -/// @param out_block .len must be >= count * (sizeof(MessageMeta) + MESSAGE_SIZE_MAX) +/// @brief try to find count messages with id >= first_message_id +/// @param dst_block writes messages here. messages_count can be 0 if no messages were found Result(void) Channel_loadMessageBlock(ServerQueries* q, i64 channel_id, i64 first_message_id, u32 count, - MessageBlockMeta* out_block_meta, Array(u8) out_block_data); + MessageBlock* dst_block); /// @return existing user id or 0 diff --git a/src/server/responses/GetMessageBlock.c b/src/server/responses/GetMessageBlock.c index 3ac8ccc..3fdde6e 100644 --- a/src/server/responses/GetMessageBlock.c +++ b/src/server/responses/GetMessageBlock.c @@ -21,8 +21,8 @@ declare_RequestHandler(GetMessageBlock) Return RESULT_VOID; } - // validate message_count - if(req.message_count < 1 || req.message_count > MESSAGE_BLOCK_COUNT_MAX){ + // validate messages_count + if(req.messages_count < 1 || req.messages_count > MESSAGE_BLOCK_COUNT_MAX){ try_void(sendErrorMessage(log_ctx, conn, res_head, LogSeverity_Warn, STR("invalid message count in request") )); Return RESULT_VOID; @@ -36,21 +36,20 @@ declare_RequestHandler(GetMessageBlock) Return RESULT_VOID; } - // reset block meta - zeroStruct(&conn->message_block_meta); // get message block from channel try_void(Channel_loadMessageBlock(conn->queries, - req.channel_id, req.first_message_id, req.message_count, - &conn->message_block_meta, conn->message_block)); + req.channel_id, req.first_message_id, req.messages_count, + &conn->message_block)); // send response GetMessageBlockResponse res; - GetMessageBlockResponse_construct(&res, res_head, &conn->message_block_meta); + GetMessageBlockResponse_construct(&res, res_head, + conn->message_block.messages_count, conn->message_block.offset); try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head)); try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res)); - if(conn->message_block_meta.data_size != 0){ + if(conn->message_block.offset != 0){ try_void(EncryptedSocketTCP_send(&conn->sock, - Array_u8_sliceTo(conn->message_block, conn->message_block_meta.data_size)) + Array_u8_sliceTo(conn->message_block.datum, conn->message_block.offset)) ); } diff --git a/src/server/server.c b/src/server/server.c index cb193f2..6db2c62 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -1,5 +1,4 @@ #include -#include "tlibc/filesystem.h" #include "tlibc/time.h" #include "server/server_internal.h" #include "server/responses/responses.h" diff --git a/src/server/server_internal.h b/src/server/server_internal.h index 2044f11..bf52ccc 100644 --- a/src/server/server_internal.h +++ b/src/server/server_internal.h @@ -38,9 +38,8 @@ typedef struct ClientConnection { i64 user_id; // 0 for unauthorized /* buffers */ - MessageBlockMeta message_block_meta; - Array(u8) message_block; - Array(u8) message_content; + MessageBlock message_block; // requested message block + Array(u8) message_content; // sent message /* database */ tsqlite_connection* db;