moved request handlers to separate files

This commit is contained in:
Timerix 2025-11-09 02:06:33 +05:00
parent ea4a649e00
commit 96a117bc50
10 changed files with 184 additions and 107 deletions

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <stdio.h> #include <stdio.h>
#define log(context, severity, format, ...) printf("[%s][" severity "]: " format "\n", context ,##__VA_ARGS__) #define log(context, severity, format, ...) printf("[%s/" severity "]: " format "\n", context ,##__VA_ARGS__)
#define logDebug(context, format, ...) log(context, "DEBUG", format ,##__VA_ARGS__) #define logDebug(context, format, ...) log(context, "DEBUG", format ,##__VA_ARGS__)
#define logInfo(context, format, ...) log(context, "INFO", format ,##__VA_ARGS__) #define logInfo(context, format, ...) log(context, "INFO", format ,##__VA_ARGS__)
#define logWarning(context, format, ...) log(context, "WARNING", format ,##__VA_ARGS__) #define logWarn(context, format, ...) log(context, "WARN", format ,##__VA_ARGS__)
#define logError(context, format, ...) log(context, "ERROR", format ,##__VA_ARGS__) #define logError(context, format, ...) log(context, "ERROR", format ,##__VA_ARGS__)

View File

@ -10,7 +10,7 @@ void ClientConnection_close(ClientConnection* conn){
} }
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials, Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
Socket sock_tcp, EndpointIPv4 client_end, u64 session_id) ConnectionHandlerArgs* args)
{ {
Deferral(32); Deferral(32);
@ -22,13 +22,14 @@ Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_cred
ClientConnection_close(conn); ClientConnection_close(conn);
); );
conn->client_end = client_end; conn->client_end = args->client_end;
conn->session_id = session_id; conn->session_id = args->session_id;
conn->authorized = false;
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE); conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
// correct session key will be received from client later // correct session key will be received from client later
Array_memset(conn->session_key, 0); Array_memset(conn->session_key, 0);
EncryptedSocketTCP_construct(&conn->sock, sock_tcp, NETWORK_BUFFER_SIZE, conn->session_key); EncryptedSocketTCP_construct(&conn->sock, args->accepted_socket, NETWORK_BUFFER_SIZE, conn->session_key);
try_void(socket_TCP_enableAliveChecks_default(sock_tcp)); try_void(socket_TCP_enableAliveChecks_default(args->accepted_socket));
// decrypt the rsa messages using server private key // decrypt the rsa messages using server private key
RSADecryptor rsa_dec; RSADecryptor rsa_dec;
@ -52,7 +53,7 @@ Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_cred
// send PacketHeader and ServerHandshake over encrypted TCP socket // send PacketHeader and ServerHandshake over encrypted TCP socket
ServerHandshake server_handshake = {0}; ServerHandshake server_handshake = {0};
ServerHandshake_construct(&server_handshake, &packet_header, ServerHandshake_construct(&server_handshake, &packet_header,
session_id); conn->session_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &packet_header)); try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &packet_header));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &server_handshake)); try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &server_handshake));

View File

@ -0,0 +1,25 @@
#include "request_handlers.h"
declare_RequestHandler(Login)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
LoginRequest req = {0};
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try authorize client
u64 user_id;
u64 landing_channel_id;
LoginResponse res = {0};
LoginResponse_construct(&res, res_head, user_id, landing_channel_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
conn->authorized = true;
logInfo(log_ctx, "client authorized");
Return RESULT_VOID;
}

View File

@ -0,0 +1,21 @@
#include "request_handlers.h"
declare_RequestHandler(Register)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
RegisterRequest req = {0};
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try register client
u64 user_id;
RegisterResponse res = {0};
RegisterResponse_construct(&res, res_head, user_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
Return RESULT_VOID;
}

View File

@ -0,0 +1,21 @@
#include "request_handlers.h"
declare_RequestHandler(ServerPublicInfo)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
ServerPublicInfoRequest req = {0};
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try find requested info
Array(u8) content;
PacketHeader_construct(res_head,
PROTOCOL_VERSION, PacketType_ServerPublicInfoResponse, content.size);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_send(&conn->sock, content));
Return RESULT_VOID;
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "network/tcp-chat-protocol/v1.h"
#include "server/server.h"
#include "log.h"
Result(char*) __sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
u32 msg_buf_size, cstr format, va_list argv);
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
u32 msg_buf_size, cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(5, 6);
#define declare_RequestHandler(TYPE) \
Result(void) handleRequest_##TYPE( \
cstr log_ctx, cstr req_type_name, \
ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head)
#define case_handleRequest(TYPE) \
case PacketType_##TYPE##Request:\
try_void(handleRequest_##TYPE(log_ctx, #TYPE, conn, &req_head, &res_head));\
break;
declare_RequestHandler(ServerPublicInfo);
declare_RequestHandler(Login);
declare_RequestHandler(Register);

View File

@ -0,0 +1,31 @@
#include "request_handlers.h"
Result(char*) __sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
u32 msg_buf_size, cstr format, va_list argv)
{
Deferral(4);
//TODO: limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
Array(u8) err_buf = Array_alloc(u8, msg_buf_size);
bool err_complete = false;
Defer(if(!err_complete) free(err_buf.data));
vsprintf(err_buf.data, format, argv);
err_buf.size = strlen(err_buf.data);
PacketHeader_construct(res_head,
PROTOCOL_VERSION, PacketType_ErrorMessage, err_buf.size);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_send(&conn->sock, err_buf));
err_complete = true;
Return RESULT_VALUE(p, err_buf.data);
}
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* req_head, PacketHeader* res_head,
u32 msg_buf_size, cstr format, ...)
{
va_list argv;
va_start(argv, format);
ResultVar(char*) err_msg = __sendErrorMessage(conn, req_head, res_head, msg_buf_size, format, argv);
va_end(argv);
return err_msg;
}

View File

@ -0,0 +1,9 @@
#include "request_handlers.h"
declare_RequestHandler(T)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
Return RESULT_VOID;
}

View File

@ -6,12 +6,7 @@
#include "config.h" #include "config.h"
#include "log.h" #include "log.h"
#include "network/tcp-chat-protocol/v1.h" #include "network/tcp-chat-protocol/v1.h"
#include "server/request_handlers/request_handlers.h"
typedef struct ConnectionHandlerArgs {
Socket accepted_socket;
EndpointIPv4 client_end;
u64 session_id;
} ConnectionHandlerArgs;
static void* handle_connection(void* _args); static void* handle_connection(void* _args);
static Result(void) try_handle_connection(ConnectionHandlerArgs* args, cstr log_ctx); static Result(void) try_handle_connection(ConnectionHandlerArgs* args, cstr log_ctx);
@ -50,7 +45,7 @@ static Result(void) parseConfig(cstr config_path){
Result(void) server_run(cstr server_endpoint_cstr, cstr config_path){ Result(void) server_run(cstr server_endpoint_cstr, cstr config_path){
Deferral(32); Deferral(32);
cstr log_ctx = "Server/MainThread"; cstr log_ctx = "MainThread";
logInfo(log_ctx, "starting server"); logInfo(log_ctx, "starting server");
logDebug(log_ctx, "parsing config"); logDebug(log_ctx, "parsing config");
try_void(parseConfig(config_path)); try_void(parseConfig(config_path));
@ -104,99 +99,38 @@ static Result(void) try_handle_connection(ConnectionHandlerArgs* args, cstr log_
logInfo(log_ctx, "session closed"); logInfo(log_ctx, "session closed");
); );
// establish encrypted connection // establish encrypted connection
try(conn, p, try(conn, p, ClientConnection_accept(_server_credentials, args));
ClientConnection_accept(
_server_credentials,
args->accepted_socket,
args->client_end,
args->session_id
)
);
logInfo(log_ctx, "session accepted"); logInfo(log_ctx, "session accepted");
// handle unauthorized requests // handle requests
bool ahtorized = false; PacketHeader req_head = {0};
PacketHeader req_header = {0}; PacketHeader res_head = {0};
PacketHeader res_header = {0}; while(true){
while(!ahtorized){ sleepMsec(20);
sleepMsec(50);
//TODO: implement some additional check if socket is dead or not //TODO: implement some additional check if socket is dead or not
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req_header)); try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req_head));
try_void(PacketHeader_validateMagic(&req_header)); try_void(PacketHeader_validateMagic(&req_head));
//TODO: move request handlers to separate functions
switch(req_header.type){
default:{
Array(u8) err_buf = Array_alloc(u8, 128);
bool err_complete = false;
Defer(if(!err_complete) free(err_buf.data));
sprintf(err_buf.data, "Received unexpected packet of type %u",
req_header.type);
err_buf.size = strlen(err_buf.data);
PacketHeader_construct(&res_header, switch(req_head.type){
PROTOCOL_VERSION, PacketType_ErrorMessage, err_buf.size); // send error message and close connection
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res_header)); default:
//TODO: limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size try(char* err_msg, p,
try_void(EncryptedSocketTCP_send(&conn->sock, err_buf)); sendErrorMessage(
conn, &req_head, &res_head,
128, "Received unexpected packet of type %u",
req_head.type
)
);
logWarn(log_ctx, "%s", err_msg);
Return RESULT_VOID;
err_complete = true; // unauthorized requests
Return RESULT_ERROR(err_buf.data, true); case_handleRequest(ServerPublicInfo);
case_handleRequest(Login);
case_handleRequest(Register);
// authorized requests
} }
case PacketType_ServerPublicInfoRequest:{
ServerPublicInfoRequest req = {0};
try_void(PacketHeader_validateContentSize(&req_header, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try find requested info
Array(u8) content;
PacketHeader_construct(&res_header,
PROTOCOL_VERSION, PacketType_ServerPublicInfoResponse, content.size);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res_header));
try_void(EncryptedSocketTCP_send(&conn->sock, content));
break;
}
case PacketType_LoginRequest:{
LoginRequest req = {0};
try_void(PacketHeader_validateContentSize(&req_header, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try authorize client
u64 user_id;
u64 landing_channel_id;
LoginResponse res = {0};
LoginResponse_construct(&res, &res_header, user_id, landing_channel_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res_header));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
ahtorized = true;
logInfo(log_ctx, "client authorized");
break;
}
case PacketType_RegisterRequest:{
RegisterRequest req = {0};
try_void(PacketHeader_validateContentSize(&req_header, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try register client
u64 user_id;
RegisterResponse res = {0};
RegisterResponse_construct(&res, &res_header, user_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res_header));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
break;
}
}
}
// handle authorized requests
while(true){
sleepMsec(50);
} }
Return RESULT_VOID; Return RESULT_VOID;

View File

@ -16,10 +16,10 @@ Result(ServerCredentials*) ServerCredentials_create(cstr rsa_sk_base64, cstr rsa
void ServerCredentials_free(ServerCredentials* cred); void ServerCredentials_free(ServerCredentials* cred);
typedef struct ServerMetadata { typedef struct ServerInfo {
str name; str name;
str description; str description;
} ServerMetadata; } ServerInfo;
typedef struct ClientConnection { typedef struct ClientConnection {
@ -27,9 +27,17 @@ typedef struct ClientConnection {
EndpointIPv4 client_end; EndpointIPv4 client_end;
Array(u8) session_key; Array(u8) session_key;
EncryptedSocketTCP sock; EncryptedSocketTCP sock;
bool authorized;
} ClientConnection; } ClientConnection;
typedef struct ConnectionHandlerArgs {
Socket accepted_socket;
EndpointIPv4 client_end;
u64 session_id;
} ConnectionHandlerArgs;
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials, Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
Socket sock, EndpointIPv4 client_end, u64 session_id); ConnectionHandlerArgs* args);
void ClientConnection_close(ClientConnection* conn); void ClientConnection_close(ClientConnection* conn);