added definitions for sending and receiving messages
This commit is contained in:
parent
0abee3f7df
commit
571fdd900f
@ -1,8 +1,8 @@
|
|||||||
|
#include "tlibc/filesystem.h"
|
||||||
|
#include "tcp-chat/common_constants.h"
|
||||||
#include "cli/ClientCLI/ClientCLI.h"
|
#include "cli/ClientCLI/ClientCLI.h"
|
||||||
#include "cli/term.h"
|
#include "cli/term.h"
|
||||||
#include "tcp-chat/common_constants.h"
|
#include "network/tcp-chat-protocol/v1.h"
|
||||||
#include "tlibc/time.h"
|
|
||||||
#include "tlibc/filesystem.h"
|
|
||||||
|
|
||||||
static const str greeting_art = STR(
|
static const str greeting_art = STR(
|
||||||
" ^,,^ ╱|\n"
|
" ^,,^ ╱|\n"
|
||||||
@ -108,11 +108,11 @@ static Result(void) ClientCLI_askUserNameAndPassword(str* username_out, str* pas
|
|||||||
try_void(term_readLine(username_buf.data, username_buf.size));
|
try_void(term_readLine(username_buf.data, username_buf.size));
|
||||||
username = str_from_cstr(username_buf.data);
|
username = str_from_cstr(username_buf.data);
|
||||||
str_trim(&username, true);
|
str_trim(&username, true);
|
||||||
if(username.size < USERNAME_SIZE_MIN || username.size > USERNAME_SIZE_MAX){
|
str name_error_str = validateUsername_str(username);
|
||||||
printf("ERROR: username length (in bytes) must be >= %i and <= %i\n",
|
if(name_error_str.data){
|
||||||
USERNAME_SIZE_MIN, USERNAME_SIZE_MAX);
|
printf("ERROR: "FMT_str"\n",
|
||||||
|
name_error_str.size, name_error_str.data);
|
||||||
}
|
}
|
||||||
//TODO: validate username characters
|
|
||||||
else break;
|
else break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include "tlibc/collections/List.h"
|
#include "tlibc/collections/List.h"
|
||||||
#include "tcp-chat/client.h"
|
#include "tcp-chat/client.h"
|
||||||
#include "db/idb.h"
|
#include "db/idb.h"
|
||||||
#include "cli/ClientCLI/db_tables.h"
|
#include "db/tables.h"
|
||||||
|
|
||||||
typedef struct ClientCLI {
|
typedef struct ClientCLI {
|
||||||
Client* client;
|
Client* client;
|
||||||
|
|||||||
@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "tcp-chat/common_constants.h"
|
|
||||||
#include "tlibc/time.h"
|
|
||||||
|
|
||||||
typedef struct ServerInfo {
|
|
||||||
u16 address_len;
|
|
||||||
char address[HOSTADDR_SIZE_MAX + 1];
|
|
||||||
u32 pk_base64_len;
|
|
||||||
char pk_base64[PUBLIC_KEY_BASE64_SIZE_MAX + 1];
|
|
||||||
u16 name_len;
|
|
||||||
char name[SERVER_NAME_SIZE_MAX + 1];
|
|
||||||
u16 desc_len;
|
|
||||||
char desc[SERVER_DESC_SIZE_MAX + 1];
|
|
||||||
} ATTRIBUTE_ALIGNED(16*1024) ServerInfo;
|
|
||||||
44
src/db/tables.h
Normal file
44
src/db/tables.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "tcp-chat/common_constants.h"
|
||||||
|
#include "tlibc/time.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct UserInfo {
|
||||||
|
u16 name_len;
|
||||||
|
char name[USERNAME_SIZE_MAX + 1]; // null-terminated
|
||||||
|
u8 token[PASSWORD_HASH_SIZE]; // token is hashed again on server side
|
||||||
|
DateTime registration_time_utc;
|
||||||
|
} ATTRIBUTE_ALIGNED(256) UserInfo;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ServerInfo {
|
||||||
|
u16 address_len;
|
||||||
|
char address[HOSTADDR_SIZE_MAX + 1];
|
||||||
|
u32 pk_base64_len;
|
||||||
|
char pk_base64[PUBLIC_KEY_BASE64_SIZE_MAX + 1];
|
||||||
|
u16 name_len;
|
||||||
|
char name[SERVER_NAME_SIZE_MAX + 1];
|
||||||
|
u16 desc_len;
|
||||||
|
char desc[SERVER_DESC_SIZE_MAX + 1];
|
||||||
|
} ATTRIBUTE_ALIGNED(16*1024) ServerInfo;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct ChannelInfo {
|
||||||
|
u16 name_len;
|
||||||
|
char name[CHANNEL_NAME_SIZE_MAX + 1];
|
||||||
|
u16 desc_len;
|
||||||
|
char desc[CHANNEL_DESC_SIZE_MAX + 1];
|
||||||
|
} ATTRIBUTE_ALIGNED(4*1024) ChannelInfo;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct MessageMetadata {
|
||||||
|
DateTime receiving_time_utc;
|
||||||
|
u64 sender_id;
|
||||||
|
u16 data_size;
|
||||||
|
} ATTRIBUTE_ALIGNED(64) MessageMetadata;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct MessageBlock {
|
||||||
|
/* sequence of messages (MessageMetadata, byte[]) */
|
||||||
|
u8 data[16*1024];
|
||||||
|
} MessageBlock;
|
||||||
@ -14,6 +14,7 @@ typedef struct PacketHeader {
|
|||||||
u8 _reserved1;
|
u8 _reserved1;
|
||||||
u16 type;
|
u16 type;
|
||||||
u32 _reserved4;
|
u32 _reserved4;
|
||||||
|
/* size of request/response struct */
|
||||||
u64 content_size;
|
u64 content_size;
|
||||||
} ATTRIBUTE_ALIGNED(64) PacketHeader;
|
} ATTRIBUTE_ALIGNED(64) PacketHeader;
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_str){
|
str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_str){
|
||||||
// must end with 0
|
// must end with 0
|
||||||
if(username[USERNAME_SIZE_MAX] != '\0'){
|
if(username[USERNAME_SIZE_MAX] != '\0'){
|
||||||
return STR("Username string doesn't end correctly");
|
return str_copy(STR("Username string doesn't end correctly"));
|
||||||
}
|
}
|
||||||
|
|
||||||
str u = str_from_cstr(username);
|
str u = str_from_cstr(username);
|
||||||
@ -16,8 +16,13 @@ str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_
|
|||||||
}
|
}
|
||||||
|
|
||||||
str validateUsername_str(str username){
|
str validateUsername_str(str username){
|
||||||
if(username.size < USERNAME_SIZE_MIN){
|
if(username.size < USERNAME_SIZE_MIN || username.size > USERNAME_SIZE_MAX){
|
||||||
return STR("Username length is too small");
|
return str_from_cstr(
|
||||||
|
sprintf_malloc(
|
||||||
|
"username length (in bytes) must be >= %i and <= %i\n",
|
||||||
|
USERNAME_SIZE_MIN, USERNAME_SIZE_MAX
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(u32 i = 0; i < username.size; i++){
|
for(u32 i = 0; i < username.size; i++){
|
||||||
@ -28,8 +33,8 @@ str validateUsername_str(str username){
|
|||||||
c == '.' || c == '_' || c == '-')
|
c == '.' || c == '_' || c == '-')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
return STR("Username contains restricted characters. "
|
return str_copy(STR("Username contains restricted characters. "
|
||||||
"Allowed characters: latin, digits, ._-");
|
"Allowed characters: latin, digits, ._-"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return str_null;
|
return str_null;
|
||||||
@ -88,9 +93,9 @@ Result(void) LoginRequest_tryConstruct(LoginRequest *ptr, PacketHeader* header,
|
|||||||
_PacketHeader_construct(LoginRequest);
|
_PacketHeader_construct(LoginRequest);
|
||||||
memset(ptr, 0, sizeof(*ptr));
|
memset(ptr, 0, sizeof(*ptr));
|
||||||
|
|
||||||
str username_check_error = validateUsername_str(username);
|
str name_error_str = validateUsername_str(username);
|
||||||
if(username_check_error.data){
|
if(name_error_str.data){
|
||||||
Return RESULT_ERROR(username_check_error.data, false);
|
Return RESULT_ERROR(name_error_str.data, true);
|
||||||
}
|
}
|
||||||
memcpy(ptr->username, username.data, username.size);
|
memcpy(ptr->username, username.data, username.size);
|
||||||
|
|
||||||
@ -117,9 +122,9 @@ Result(void) RegisterRequest_tryConstruct(RegisterRequest *ptr, PacketHeader* he
|
|||||||
_PacketHeader_construct(RegisterRequest);
|
_PacketHeader_construct(RegisterRequest);
|
||||||
memset(ptr, 0, sizeof(*ptr));
|
memset(ptr, 0, sizeof(*ptr));
|
||||||
|
|
||||||
str username_check_error = validateUsername_str(username);
|
str name_error_str = validateUsername_str(username);
|
||||||
if(username_check_error.data){
|
if(name_error_str.data){
|
||||||
Return RESULT_ERROR(username_check_error.data, false);
|
Return RESULT_ERROR(name_error_str.data, true);
|
||||||
}
|
}
|
||||||
memcpy(ptr->username, username.data, username.size);
|
memcpy(ptr->username, username.data, username.size);
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "tlibc/errors.h"
|
#include "tlibc/errors.h"
|
||||||
#include "tlibc/string/str.h"
|
#include "tlibc/string/str.h"
|
||||||
|
#include "tlibc/time.h"
|
||||||
#include "network/tcp-chat-protocol/constant.h"
|
#include "network/tcp-chat-protocol/constant.h"
|
||||||
|
|
||||||
#define PROTOCOL_VERSION 1 /* 1.0.0 */
|
#define PROTOCOL_VERSION 1 /* 1.0.0 */
|
||||||
@ -15,7 +16,7 @@ Valid username:
|
|||||||
- allowed characters: latin, digits, ._-
|
- allowed characters: latin, digits, ._-
|
||||||
*/
|
*/
|
||||||
/// validates username char[] and constructs str from it
|
/// validates username char[] and constructs str from it
|
||||||
/// @return str_null on success, stack-allocated error message on fail
|
/// @return str_null on success, heap-allocated error message on fail
|
||||||
str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_str) ATTRIBUTE_WARN_UNUSED_RESULT;
|
str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_str) ATTRIBUTE_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
str validateUsername_str(str username) ATTRIBUTE_WARN_UNUSED_RESULT;
|
str validateUsername_str(str username) ATTRIBUTE_WARN_UNUSED_RESULT;
|
||||||
@ -119,3 +120,38 @@ void RegisterResponse_construct(RegisterResponse* ptr, PacketHeader* header,
|
|||||||
u64 user_id);
|
u64 user_id);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SendMessageRequest {
|
||||||
|
u64 channel_id;
|
||||||
|
u16 data_size;
|
||||||
|
/* stream of size data_size */
|
||||||
|
} ALIGN_PACKET_STRUCT SendMessageRequest;
|
||||||
|
|
||||||
|
void SendMessageRequest_construct(SendMessageRequest* ptr, PacketHeader* header,
|
||||||
|
u64 channel_id, u16 data_size);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct SendMessageResponse {
|
||||||
|
u64 message_id;
|
||||||
|
DateTime receiving_time_utc;
|
||||||
|
} ALIGN_PACKET_STRUCT SendMessageResponse;
|
||||||
|
|
||||||
|
void SendMessageResponse_construct(SendMessageResponse* ptr, PacketHeader* header,
|
||||||
|
u64 message_id, DateTime receiving_time_utc);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct GetMessageBlockRequest {
|
||||||
|
u64 message_block_id;
|
||||||
|
} ALIGN_PACKET_STRUCT GetMessageBlockRequest;
|
||||||
|
|
||||||
|
void GetMessageBlockRequest_construct(GetMessageBlockRequest* ptr, PacketHeader* header,
|
||||||
|
u64 message_block_id);
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct GetMessageBlockResponse {
|
||||||
|
u32 data_size;
|
||||||
|
/* stream of size data_size */
|
||||||
|
} ALIGN_PACKET_STRUCT GetMessageBlockResponse;
|
||||||
|
|
||||||
|
void GetMessageBlockResponse_construct(GetMessageBlockResponse* ptr, PacketHeader* header,
|
||||||
|
u32 data_size);
|
||||||
|
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "tcp-chat/common_constants.h"
|
|
||||||
#include "tlibc/time.h"
|
|
||||||
|
|
||||||
typedef struct UserInfo {
|
|
||||||
u16 name_len;
|
|
||||||
char name[USERNAME_SIZE_MAX + 1]; // null-terminated
|
|
||||||
u8 token[PASSWORD_HASH_SIZE]; // token is hashed again on server side
|
|
||||||
DateTime registration_time;
|
|
||||||
} ATTRIBUTE_ALIGNED(256) UserInfo;
|
|
||||||
|
|
||||||
typedef struct ChannelInfo {
|
|
||||||
u16 name_len;
|
|
||||||
char name[CHANNEL_NAME_SIZE_MAX + 1];
|
|
||||||
u16 desc_len;
|
|
||||||
char desc[CHANNEL_DESC_SIZE_MAX + 1];
|
|
||||||
} ATTRIBUTE_ALIGNED(4*1024) ChannelInfo;
|
|
||||||
23
src/server/responses/GetMessageBlock.c
Normal file
23
src/server/responses/GetMessageBlock.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "responses.h"
|
||||||
|
|
||||||
|
#define LOGGER conn->server->logger
|
||||||
|
#define LOG_FUNC conn->server->log_func
|
||||||
|
|
||||||
|
declare_RequestHandler(GetMessageBlock)
|
||||||
|
{
|
||||||
|
Deferral(4);
|
||||||
|
logInfo(log_ctx, "requested %s", req_type_name);
|
||||||
|
|
||||||
|
// receive request
|
||||||
|
GetMessageBlockRequest req;
|
||||||
|
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
|
||||||
|
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
|
||||||
|
|
||||||
|
// send response
|
||||||
|
GetMessageBlockResponse res;
|
||||||
|
GetMessageBlockResponse_construct(&res, res_head, );
|
||||||
|
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||||
|
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||||
|
|
||||||
|
Return RESULT_VOID;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "request_handlers.h"
|
#include "responses.h"
|
||||||
|
|
||||||
#define LOGGER conn->server->logger
|
#define LOGGER conn->server->logger
|
||||||
#define LOG_FUNC conn->server->log_func
|
#define LOG_FUNC conn->server->log_func
|
||||||
@ -23,11 +23,12 @@ declare_RequestHandler(Login)
|
|||||||
|
|
||||||
// validate username
|
// validate username
|
||||||
str username_str = str_null;
|
str username_str = str_null;
|
||||||
str username_check_error = validateUsername_cstr(req.username, &username_str);
|
str name_error_str = validateUsername_cstr(req.username, &username_str);
|
||||||
if(username_check_error.data){
|
if(name_error_str.data){
|
||||||
|
Defer(str_free(name_error_str));
|
||||||
try_void(sendErrorMessage(log_ctx, conn, res_head,
|
try_void(sendErrorMessage(log_ctx, conn, res_head,
|
||||||
LogSeverity_Warn,
|
LogSeverity_Warn,
|
||||||
username_check_error
|
name_error_str
|
||||||
));
|
));
|
||||||
Return RESULT_VOID;
|
Return RESULT_VOID;
|
||||||
}
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "request_handlers.h"
|
#include "responses.h"
|
||||||
|
|
||||||
#define LOGGER conn->server->logger
|
#define LOGGER conn->server->logger
|
||||||
#define LOG_FUNC conn->server->log_func
|
#define LOG_FUNC conn->server->log_func
|
||||||
@ -23,11 +23,12 @@ declare_RequestHandler(Register)
|
|||||||
|
|
||||||
// validate username
|
// validate username
|
||||||
str username_str = str_null;
|
str username_str = str_null;
|
||||||
str username_check_error = validateUsername_cstr(req.username, &username_str);
|
str name_error_str = validateUsername_cstr(req.username, &username_str);
|
||||||
if(username_check_error.data){
|
if(name_error_str.data){
|
||||||
|
Defer(str_free(name_error_str));
|
||||||
try_void(sendErrorMessage(log_ctx, conn, res_head,
|
try_void(sendErrorMessage(log_ctx, conn, res_head,
|
||||||
LogSeverity_Warn,
|
LogSeverity_Warn,
|
||||||
username_check_error
|
name_error_str
|
||||||
));
|
));
|
||||||
Return RESULT_VOID;
|
Return RESULT_VOID;
|
||||||
}
|
}
|
||||||
@ -59,7 +60,7 @@ declare_RequestHandler(Register)
|
|||||||
|
|
||||||
memcpy(user.token, req.token, sizeof(req.token));
|
memcpy(user.token, req.token, sizeof(req.token));
|
||||||
|
|
||||||
DateTime_getUTC(&user.registration_time);
|
DateTime_getUTC(&user.registration_time_utc);
|
||||||
|
|
||||||
// save new user to db and cache
|
// save new user to db and cache
|
||||||
try(u64 user_id, u, idb_pushRow(conn->server->db_users_table, &user));
|
try(u64 user_id, u, idb_pushRow(conn->server->db_users_table, &user));
|
||||||
23
src/server/responses/SendMessage.c
Normal file
23
src/server/responses/SendMessage.c
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#include "responses.h"
|
||||||
|
|
||||||
|
#define LOGGER conn->server->logger
|
||||||
|
#define LOG_FUNC conn->server->log_func
|
||||||
|
|
||||||
|
declare_RequestHandler(SendMessage)
|
||||||
|
{
|
||||||
|
Deferral(4);
|
||||||
|
logInfo(log_ctx, "requested %s", req_type_name);
|
||||||
|
|
||||||
|
// receive request
|
||||||
|
SendMessageRequest req;
|
||||||
|
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
|
||||||
|
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
|
||||||
|
|
||||||
|
// send response
|
||||||
|
SendMessageResponse res;
|
||||||
|
SendMessageResponse_construct(&res, res_head, );
|
||||||
|
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
|
||||||
|
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
|
||||||
|
|
||||||
|
Return RESULT_VOID;
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "request_handlers.h"
|
#include "responses.h"
|
||||||
|
|
||||||
#define LOGGER conn->server->logger
|
#define LOGGER conn->server->logger
|
||||||
#define LOG_FUNC conn->server->log_func
|
#define LOG_FUNC conn->server->log_func
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "request_handlers.h"
|
#include "responses.h"
|
||||||
|
|
||||||
#define LOGGER conn->server->logger
|
#define LOGGER conn->server->logger
|
||||||
#define LOG_FUNC conn->server->log_func
|
#define LOG_FUNC conn->server->log_func
|
||||||
@ -1,4 +1,4 @@
|
|||||||
#include "request_handlers.h"
|
#include "responses.h"
|
||||||
|
|
||||||
#define LOGGER conn->server->logger
|
#define LOGGER conn->server->logger
|
||||||
#define LOG_FUNC conn->server->log_func
|
#define LOG_FUNC conn->server->log_func
|
||||||
@ -5,7 +5,7 @@
|
|||||||
#include "server/server_internal.h"
|
#include "server/server_internal.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "network/tcp-chat-protocol/v1.h"
|
#include "network/tcp-chat-protocol/v1.h"
|
||||||
#include "server/request_handlers/request_handlers.h"
|
#include "server/responses/responses.h"
|
||||||
|
|
||||||
static void* handleConnection(void* _args);
|
static void* handleConnection(void* _args);
|
||||||
static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_ctx);
|
static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_ctx);
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
#include "cryptography/RSA.h"
|
#include "cryptography/RSA.h"
|
||||||
#include "network/encrypted_sockets.h"
|
#include "network/encrypted_sockets.h"
|
||||||
#include "db/idb.h"
|
#include "db/idb.h"
|
||||||
#include "server/db_tables.h"
|
#include "db/tables.h"
|
||||||
|
|
||||||
typedef struct ClientConnection ClientConnection;
|
typedef struct ClientConnection ClientConnection;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user