implemented LoginRequest handler, changed ErrorMessage and ServerPublicInfoResponse

This commit is contained in:
Timerix 2025-11-15 12:14:33 +05:00
parent ef2531c63b
commit 9942d94c94
17 changed files with 285 additions and 110 deletions

2
dependencies/tlibc vendored

@ -1 +1 @@
Subproject commit adaf5cc31199b8b70404f30b51a0e4ef822d6fab
Subproject commit ae0fa95d6aee2a7427c3e3575d74af1ed360e6e5

View File

@ -66,8 +66,8 @@ Result(ServerConnection*) ServerConnection_open(cstr server_link_cstr){
// send PacketHeader and ClientHandshake
// encryption by server public key
PacketHeader packet_header = {0};
ClientHandshake client_handshake = {0};
PacketHeader packet_header;
ClientHandshake client_handshake;
try_void(ClientHandshake_tryConstruct(&client_handshake, &packet_header,
conn->session_key));
try_void(EncryptedSocketTCP_sendStructRSA(&conn->sock, &conn->rsa_enc, &packet_header));
@ -80,26 +80,24 @@ Result(ServerConnection*) ServerConnection_open(cstr server_link_cstr){
// handle server response
switch(packet_header.type){
case PacketType_ErrorMessage: {
u32 err_msg_size = packet_header.content_size;
if(err_msg_size > conn->sock.recv_buf.size)
err_msg_size = conn->sock.recv_buf.size;
Array(u8) err_buf = Array_alloc_size(err_msg_size + 1);
ErrorMessage err_msg;
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &err_msg));
if(err_msg.msg_size > conn->sock.recv_buf.size)
err_msg.msg_size = conn->sock.recv_buf.size;
Array(u8) err_buf = Array_alloc_size(err_msg.msg_size + 1);
bool err_msg_completed = false;
Defer(
if(!err_msg_completed)
free(err_buf.data);
);
Defer(if(!err_msg_completed) free(err_buf.data));
// receive error message
// receive message content
try_void(
EncryptedSocketTCP_recv(
&conn->sock,
Array_sliceTo(err_buf, err_msg_size),
Array_sliceTo(err_buf, err_msg.msg_size),
SocketRecvFlag_WholeBuffer
)
);
((u8*)err_buf.data)[err_msg_size] = 0;
((u8*)err_buf.data)[err_msg.msg_size] = 0;
err_msg_completed = true;
Return RESULT_ERROR((char*)err_buf.data, true);
}

View File

@ -2,7 +2,7 @@
#include "tlibc/std.h"
#define USERNAME_SIZE_MIN 2
#define USERNAME_SIZE_MAX 63
#define USERNAME_SIZE_MAX 31
#define PASSWORD_SIZE_MIN 8
#define PASSWORD_SIZE_MAX 31
#define PASSWORD_HASH_SIZE 32

View File

@ -15,7 +15,6 @@
#define AESStream_DEFAULT_CLASS (&br_aes_big_ctr_vtable)
//TODO: use PKS#7 instead of this garbage
typedef struct EncryptedBlockHeader {
u8 padding_size;
} ATTRIBUTE_ALIGNED(16) EncryptedBlockHeader;

View File

@ -286,8 +286,8 @@ Result(void) idb_getRows(Table* t, u64 id, void* dst, u64 count){
if(id + count > t->row_count){
Return RESULT_ERROR_FMT(
"Can't read " IFWIN("%llu", "%lu") " rows at index " IFWIN("%llu", "%lu")
" because table '%s' has only " IFWIN("%llu", "%lu") " rows",
"Can't read "FMT_u64" rows at index "FMT_u64
" because table '%s' has only "FMT_u64" rows",
count, id, t->name.data, t->row_count);
}
@ -325,8 +325,8 @@ Result(void) idb_updateRows(Table* t, u64 id, const void* src, u64 count){
if(id + count >= t->row_count){
Return RESULT_ERROR_FMT(
"Can't update " IFWIN("%llu", "%lu") " rows at index " IFWIN("%llu", "%lu")
" because table '%s' has only " IFWIN("%llu", "%lu") " rows",
"Can't update "FMT_u64" rows at index "FMT_u64
" because table '%s' has only "FMT_u64" rows",
count, id, t->name.data, t->row_count);
}

View File

@ -21,14 +21,15 @@ Result(void) PacketHeader_validateType(PacketHeader* ptr, u16 expected_type){
Result(void) PacketHeader_validateContentSize(PacketHeader* ptr, u64 expected_size){
if(ptr->content_size != expected_size){
return RESULT_ERROR_FMT(
"expected message with content_size " IFWIN("%llu", "%lu")
", but received with content_size " IFWIN("%llu", "%lu"),
"expected message with content_size "FMT_u64
", but received with content_size "FMT_u64,
expected_size, ptr->content_size);
}
return RESULT_VOID;
}
void PacketHeader_construct(PacketHeader* ptr, u8 protocol_version, u16 type, u64 content_size){
memset(ptr, 0, sizeof(*ptr));
ptr->magic.n = PacketHeader_MAGIC.n;
ptr->protocol_version = protocol_version;
ptr->type = type;

View File

@ -1,13 +1,55 @@
#include "v1.h"
str validateUsername_cstr(char username[USERNAME_SIZE_MAX+1], str* out_username_str){
// must end with 0
if(username[USERNAME_SIZE_MAX] != '\0'){
return STR("Username string doesn't end correctly");
}
str u = str_from_cstr(username);
str error_str = validateUsername_str(u);
if(error_str.data)
return error_str;
*out_username_str = u;
return str_null;
}
str validateUsername_str(str username){
if(username.size < USERNAME_SIZE_MIN){
return STR("Username length is too small");
}
for(u32 i = 0; i < username.size; i++){
char c = username.data[i];
if (char_isLatinLower(c) ||
char_isLatinUpper(c) ||
char_isDigit(c) ||
c == '.' || c == '_' || c == '-')
continue;
return STR("Username contains restricted characters. "
"Allowed characters: latin, digits, ._-");
}
return str_null;
}
#define _PacketHeader_construct(T) \
PacketHeader_construct(header, PROTOCOL_VERSION, PacketType_##T, sizeof(T))
void ErrorMessage_construct(ErrorMessage* ptr, PacketHeader* header, u32 msg_size){
_PacketHeader_construct(ErrorMessage);
memset(ptr, 0, sizeof(*ptr));
ptr->msg_size = msg_size;
}
Result(void) ClientHandshake_tryConstruct(ClientHandshake* ptr, PacketHeader* header,
Array(u8) session_key)
{
Deferral(1);
_PacketHeader_construct(ClientHandshake);
memset(ptr, 0, sizeof(*ptr));
try_assert(session_key.size == sizeof(ptr->session_key));
memcpy(ptr->session_key, session_key.data, session_key.size);
@ -19,6 +61,7 @@ void ServerHandshake_construct(ServerHandshake* ptr, PacketHeader* header,
u64 session_id)
{
_PacketHeader_construct(ServerHandshake);
memset(ptr, 0, sizeof(*ptr));
ptr->session_id = session_id;
}
@ -26,14 +69,31 @@ void ServerPublicInfoRequest_construct(ServerPublicInfoRequest *ptr, PacketHeade
ServerPublicInfo property)
{
_PacketHeader_construct(ServerPublicInfoRequest);
memset(ptr, 0, sizeof(*ptr));
ptr->property = property;
}
void ServerPublicInfoResponse_construct(ServerPublicInfoResponse* ptr, PacketHeader* header,
u32 data_size)
{
_PacketHeader_construct(ServerPublicInfoResponse);
memset(ptr, 0, sizeof(*ptr));
ptr->data_size = data_size;
}
Result(void) LoginRequest_tryConstruct(LoginRequest *ptr, PacketHeader* header,
Array(u8) token)
str username, Array(u8) token)
{
Deferral(1);
_PacketHeader_construct(LoginRequest);
memset(ptr, 0, sizeof(*ptr));
str username_check_error = validateUsername_str(username);
if(username_check_error.data){
Return RESULT_ERROR(username_check_error.data, false);
}
memcpy(ptr->username, username.data, username.size);
ptr->username[username.size] = 0;
try_assert(token.size == sizeof(ptr->token));
memcpy(ptr->token, token.data, token.size);
@ -45,6 +105,8 @@ void LoginResponse_construct(LoginResponse* ptr, PacketHeader* header,
u64 user_id, u64 landing_channel_id)
{
_PacketHeader_construct(LoginResponse);
memset(ptr, 0, sizeof(*ptr));
ptr->user_id = user_id;
ptr->landing_channel_id = landing_channel_id;
}
@ -54,8 +116,12 @@ Result(void) RegisterRequest_tryConstruct(RegisterRequest *ptr, PacketHeader* he
{
Deferral(1);
_PacketHeader_construct(RegisterRequest);
memset(ptr, 0, sizeof(*ptr));
try_assert(username.size >= USERNAME_SIZE_MIN && username.size <= USERNAME_SIZE_MAX);
str username_check_error = validateUsername_str(username);
if(username_check_error.data){
Return RESULT_ERROR(username_check_error.data, false);
}
memcpy(ptr->username, username.data, username.size);
ptr->username[username.size] = 0;
@ -69,5 +135,6 @@ void RegisterResponse_construct(RegisterResponse *ptr, PacketHeader* header,
u64 user_id)
{
_PacketHeader_construct(RegisterResponse);
memset(ptr, 0, sizeof(*ptr));
ptr->user_id = user_id;
}

View File

@ -8,6 +8,18 @@
#define ALIGN_PACKET_STRUCT ATTRIBUTE_ALIGNED(8)
/*
Valid username:
- must end with '\0'
- USERNAME_SIZE_MIN <= size <= USERNAME_SIZE_MAX
- allowed characters: latin, digits, ._-
*/
/// validates username char[] and constructs str from it
/// @return str_null on success, stack-allocated error message on fail
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;
typedef enum PacketType {
PacketType_Invalid,
@ -23,9 +35,15 @@ typedef enum PacketType {
} ATTRIBUTE_PACKED PacketType;
// typedef struct ErrorMessage {
// /* stream of size header.content_size */
// } ErrorMessage;
#define ERROR_MESSAGE_MAX_SIZE 8192
typedef struct ErrorMessage {
u32 msg_size; // <= ERROR_MESSAGE_MAX_SIZE
/* stream of size msg_size */
} ErrorMessage;
void ErrorMessage_construct(ErrorMessage* ptr, PacketHeader* header,
u32 msg_size);
typedef struct ClientHandshake {
@ -57,17 +75,22 @@ void ServerPublicInfoRequest_construct(ServerPublicInfoRequest* ptr, PacketHeade
ServerPublicInfo property);
// typedef struct ServerPublicInfoResponse {
// /* stream of size header.content_size */
// } ServerPublicInfoResponse;
typedef struct ServerPublicInfoResponse {
u32 data_size;
/* stream of size data_size */
} ServerPublicInfoResponse;
void ServerPublicInfoResponse_construct(ServerPublicInfoResponse* ptr, PacketHeader* header,
u32 data_size);
typedef struct LoginRequest {
char username[USERNAME_SIZE_MAX + 1]; // null-terminated
u8 token[PASSWORD_HASH_SIZE];
} ALIGN_PACKET_STRUCT LoginRequest;
Result(void) LoginRequest_tryConstruct(LoginRequest* ptr, PacketHeader* header,
Array(u8) token);
str username, Array(u8) token);
typedef struct LoginResponse {

View File

@ -32,14 +32,14 @@ Result(ClientConnection*) ClientConnection_accept(ConnectionHandlerArgs* args)
RSADecryptor_construct(&rsa_dec, &args->server->cred.rsa_sk);
// receive PacketHeader
PacketHeader packet_header = {0};
PacketHeader packet_header;
try_void(EncryptedSocketTCP_recvStructRSA(&conn->sock, &rsa_dec, &packet_header));
try_void(PacketHeader_validateMagic(&packet_header));
try_void(PacketHeader_validateType(&packet_header, PacketType_ClientHandshake));
try_void(PacketHeader_validateContentSize(&packet_header, sizeof(ClientHandshake)));
// receive ClientHandshake
ClientHandshake client_handshake = {0};
ClientHandshake client_handshake;
try_void(EncryptedSocketTCP_recvStructRSA(&conn->sock, &rsa_dec, &client_handshake));
// use received session key
@ -47,7 +47,7 @@ Result(ClientConnection*) ClientConnection_accept(ConnectionHandlerArgs* args)
EncryptedSocketTCP_changeKey(&conn->sock, conn->session_key);
// send PacketHeader and ServerHandshake over encrypted TCP socket
ServerHandshake server_handshake = {0};
ServerHandshake server_handshake;
ServerHandshake_construct(&server_handshake, &packet_header,
conn->session_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &packet_header));

View File

@ -4,22 +4,74 @@
declare_RequestHandler(Login)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
logInfo(log_ctx, "requested %s", req_type_name);
LoginRequest req = {0};
// receive request
LoginRequest req;
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;
if(conn->authorized){
try_void(sendErrorMessage(log_ctx, false, conn, res_head,
STR("is logged in already")));
Return RESULT_VOID;
}
LoginResponse res = {0};
LoginResponse_construct(&res, res_head, user_id, landing_channel_id);
// validate username
str username_str = str_null;
str username_check_error = validateUsername_cstr(req.username, &username_str);
if(username_check_error.data){
try_void(sendErrorMessage(log_ctx, false, conn, res_head, username_check_error));
Return RESULT_VOID;
}
// cakculate hash of received token
u8 token_hash[PASSWORD_HASH_SIZE];
hash_password(
Array_construct_size(req.token, sizeof(req.token)),
token_hash,
PASSWORD_HASH_LVL_ROUNDS
);
// lock users cache
try_stderrcode(pthread_mutex_lock(&server->users_cache_mutex));
bool unlocked_users_cache_mutex = false;
Defer(if(!unlocked_users_cache_mutex) pthread_mutex_unlock(&server->users_cache_mutex));
// try get id from name cache
u64* id_ptr = HashMap_tryGetPtr(&server->users_name_id_map, username_str);
if(id_ptr == NULL){
try_void(sendErrorMessage_f(log_ctx, false, conn, res_head,
"Username '%s' is not registered\n",
username_str.data));
Return RESULT_VOID;
}
u64 user_id = *id_ptr;
// get user by id
try_assert(List_len(server->users_cache_list, User) < user_id);
User* u = &List_index(server->users_cache_list, User, user_id);
// validate token hash
if(memcmp(token_hash, u->token_hash, sizeof(token_hash)) != 0){
try_void(sendErrorMessage(log_ctx, false, conn, res_head,
STR("wrong password")));
Return RESULT_VOID;
}
// manually unlock mutex
pthread_mutex_unlock(&server->users_cache_mutex);
unlocked_users_cache_mutex = true;
// authorize
conn->authorized = true;
logInfo(log_ctx, "authorized user '%s'", username_str.data);
// send response
LoginResponse res;
LoginResponse_construct(&res, res_head, user_id, server->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

@ -3,29 +3,18 @@
declare_RequestHandler(Register)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
logInfo(log_ctx, "requested %s", req_type_name);
RegisterRequest req = {0};
// receive request
RegisterRequest req;
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: reject usernames with restricted characters
// must end with 0
if(req.username[sizeof(req.username - 1)] != 0){
try(char* err_msg, p, sendErrorMessage(conn, res_head,
"Username is incorrect\n"));
logWarn(log_ctx, "%s", err_msg);
free(err_msg);
Return RESULT_VOID;
}
// check username size
str username_str = str_from_cstr(req.username);
if(username_str.size < USERNAME_SIZE_MIN){
try(char* err_msg, p, sendErrorMessage(conn, res_head,
"Username length (in bytes) must be >= %i and <= %i\n",
USERNAME_SIZE_MIN, USERNAME_SIZE_MAX));
logWarn(log_ctx, "%s", err_msg);
free(err_msg);
// validate username
str username_str = str_null;
str username_check_error = validateUsername_cstr(req.username, &username_str);
if(username_check_error.data){
try_void(sendErrorMessage(log_ctx, false, conn, res_head, username_check_error));
Return RESULT_VOID;
}
@ -36,11 +25,9 @@ declare_RequestHandler(Register)
// check if name is taken
if(HashMap_tryGetPtr(&server->users_name_id_map, username_str) != NULL){
try(char* err_msg, p, sendErrorMessage(conn, res_head,
"User with name '%s' already exists\n",
try_void(sendErrorMessage_f(log_ctx, false, conn, res_head,
"Username'%s' already exists\n",
username_str.data));
logWarn(log_ctx, "%s", err_msg);
free(err_msg);
Return RESULT_VOID;
}
@ -66,7 +53,10 @@ declare_RequestHandler(Register)
pthread_mutex_unlock(&server->users_cache_mutex);
unlocked_users_cache_mutex = true;
RegisterResponse res = {0};
logInfo(log_ctx, "registered user '%s'", username_str.data);
// send response
RegisterResponse res;
RegisterResponse_construct(&res, res_head, user_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));

View File

@ -3,21 +3,20 @@
declare_RequestHandler(ServerPublicInfo)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
logInfo(log_ctx, "requested %s", req_type_name);
ServerPublicInfoRequest req = {0};
// receive request
ServerPublicInfoRequest req;
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
//TODO: try find requested info
// find requested info
Array(u8) content;
switch(req.property){
default:{
try(char* err_msg, p, sendErrorMessage(conn, res_head,
try_void(sendErrorMessage_f(log_ctx, false, conn, res_head,
"Unknown ServerPublicInfo property %u",
req.property));
logWarn(log_ctx, "%s", err_msg);
free(err_msg);
Return RESULT_VOID;
}
case ServerPublicInfo_Name:
@ -28,9 +27,11 @@ declare_RequestHandler(ServerPublicInfo)
break;
}
PacketHeader_construct(res_head,
PROTOCOL_VERSION, PacketType_ServerPublicInfoResponse, content.size);
// send response
ServerPublicInfoResponse res;
ServerPublicInfoResponse_construct(&res, res_head, content.size);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
try_void(EncryptedSocketTCP_send(&conn->sock, content));
Return RESULT_VOID;

View File

@ -4,10 +4,17 @@
#include "log.h"
Result(char*) __sendErrorMessage_va(ClientConnection* conn, PacketHeader* res_head,
Result(void) sendErrorMessage(cstr log_ctx, bool logAsError,
ClientConnection* conn, PacketHeader* res_head,
str msg);
Result(void) __sendErrorMessage_fv(cstr log_ctx, bool logAsError,
ClientConnection* conn, PacketHeader* res_head,
cstr format, va_list argv);
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* res_head,
cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(3, 4);
Result(void) sendErrorMessage_f(cstr log_ctx, bool logAsError,
ClientConnection* conn, PacketHeader* res_head,
cstr format, ...) ATTRIBUTE_CHECK_FORMAT_PRINTF(5, 6);
#define declare_RequestHandler(TYPE) \

View File

@ -1,34 +1,54 @@
#include "request_handlers.h"
#include "log.h"
Result(char*) __sendErrorMessage_va(ClientConnection* conn, PacketHeader* res_head,
Result(void) sendErrorMessage(cstr log_ctx, bool logAsError,
ClientConnection* conn, PacketHeader* res_head,
str msg)
{
Deferral(1);
//limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
if(msg.size > ERROR_MESSAGE_MAX_SIZE)
msg.size = ERROR_MESSAGE_MAX_SIZE;
if(logAsError){
logError(log_ctx, FMT_str, msg.size, msg.data);
} else {
logWarn(log_ctx, FMT_str, msg.size, msg.data);
}
ErrorMessage res;
ErrorMessage_construct(&res, res_head, msg.size);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
try_void(EncryptedSocketTCP_send(&conn->sock, str_castTo_Array(msg)));
Return RESULT_VOID;
}
Result(void) __sendErrorMessage_fv(cstr log_ctx, bool logAsError,
ClientConnection* conn, PacketHeader* res_head,
cstr format, va_list argv)
{
Deferral(4);
Array(u8) err_buf;
err_buf.data = vsprintf_malloc(format, argv);
err_buf.size = strlen(err_buf.data);
//limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
if(err_buf.size > NETWORK_BUFFER_SIZE)
err_buf.size = NETWORK_BUFFER_SIZE;
bool err_complete = false;
Defer(if(!err_complete) free(err_buf.data));
str msg = str_from_cstr(vsprintf_malloc(format, argv));
Defer(free(msg.data));
try_void(sendErrorMessage(log_ctx, logAsError, conn, res_head, msg));
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);
Return RESULT_VOID;
}
Result(char*) sendErrorMessage(ClientConnection* conn, PacketHeader* res_head,
Result(void) sendErrorMessage_f(cstr log_ctx, bool logAsError,
ClientConnection* conn, PacketHeader* res_head,
cstr format, ...)
{
Deferral(1);
va_list argv;
va_start(argv, format);
ResultVar(char*) err_msg = __sendErrorMessage_va(conn, res_head, format, argv);
va_end(argv);
return err_msg;
Defer(va_end(argv));
try_void(__sendErrorMessage_fv(log_ctx, logAsError, conn, res_head, format, argv));
return RESULT_VOID;
}

View File

@ -1,9 +1,20 @@
#include "request_handlers.h"
declare_RequestHandler(T)
declare_RequestHandler(NAME)
{
Deferral(4);
logDebug(log_ctx, "requested %s", req_type_name);
logInfo(log_ctx, "requested %s", req_type_name);
// receive request
NAME##Request req;
try_void(PacketHeader_validateContentSize(req_head, sizeof(req)));
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req));
// send response
NAME##Response res;
NAME##Response_construct(&res, res_head, );
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, res_head));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res));
Return RESULT_VOID;
}

View File

@ -52,6 +52,14 @@ Result(Server*) Server_createFromConfig(cstr config_path){
try_void(config_findValue(config_str, STR("description"), &tmp_str, true));
server->description = str_copy(tmp_str);
// parse landing_channel_id
try_void(config_findValue(config_str, STR("landing_channel_id"), &tmp_str, true));
char* lci_cstr = str_copy(tmp_str).data;
Defer(free(lci_cstr));
if(sscanf(lci_cstr, FMT_u64, &server->landing_channel_id) != 1){
Return RESULT_ERROR("can't parse 'landing_channel_id' value as number", false);
}
// parse local_address
try_void(config_findValue(config_str, STR("local_address"), &tmp_str, true));
char* local_end_cstr = str_copy(tmp_str).data;
@ -133,7 +141,7 @@ Result(void) Server_run(Server* server){
static void* handleConnection(void* _args){
ConnectionHandlerArgs* args = (ConnectionHandlerArgs*)_args;
char log_ctx[64];
sprintf(log_ctx, "Session-" IFWIN("%llx", "%lx"), args->session_id);
sprintf(log_ctx, "Session-"FMT_x64, args->session_id);
ResultVar(void) r = try_handleConnection(args, log_ctx);
if(r.error){
@ -159,8 +167,8 @@ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_c
logInfo(log_ctx, "session accepted");
// handle requests
PacketHeader req_head = {0};
PacketHeader res_head = {0};
PacketHeader req_head;
PacketHeader res_head;
while(true){
sleepMsec(20);
//TODO: implement some additional check if socket is dead or not
@ -171,12 +179,9 @@ static Result(void) try_handleConnection(ConnectionHandlerArgs* args, cstr log_c
switch(req_head.type){
// send error message and close connection
default:
try(char* err_msg, p,
sendErrorMessage(conn, &res_head,
try_void(sendErrorMessage_f(log_ctx, false, conn, &res_head,
"Received unexpected packet of type %u",
req_head.type));
logWarn(log_ctx, "%s", err_msg);
free(err_msg);
Return RESULT_VOID;
// unauthorized requests

View File

@ -45,6 +45,7 @@ void ClientConnection_close(ClientConnection* conn);
typedef struct Server {
str name;
str description;
u64 landing_channel_id;
EndpointIPv4 local_end;
ServerCredentials cred;
IncrementalDB* db;