moved request handlers to separate files
This commit is contained in:
parent
ea4a649e00
commit
96a117bc50
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#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 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__)
|
||||
|
||||
@ -10,7 +10,7 @@ void ClientConnection_close(ClientConnection* conn){
|
||||
}
|
||||
|
||||
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
|
||||
Socket sock_tcp, EndpointIPv4 client_end, u64 session_id)
|
||||
ConnectionHandlerArgs* args)
|
||||
{
|
||||
Deferral(32);
|
||||
|
||||
@ -22,13 +22,14 @@ Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_cred
|
||||
ClientConnection_close(conn);
|
||||
);
|
||||
|
||||
conn->client_end = client_end;
|
||||
conn->session_id = session_id;
|
||||
conn->client_end = args->client_end;
|
||||
conn->session_id = args->session_id;
|
||||
conn->authorized = false;
|
||||
conn->session_key = Array_alloc_size(AES_SESSION_KEY_SIZE);
|
||||
// correct session key will be received from client later
|
||||
Array_memset(conn->session_key, 0);
|
||||
EncryptedSocketTCP_construct(&conn->sock, sock_tcp, NETWORK_BUFFER_SIZE, conn->session_key);
|
||||
try_void(socket_TCP_enableAliveChecks_default(sock_tcp));
|
||||
EncryptedSocketTCP_construct(&conn->sock, args->accepted_socket, NETWORK_BUFFER_SIZE, conn->session_key);
|
||||
try_void(socket_TCP_enableAliveChecks_default(args->accepted_socket));
|
||||
|
||||
// decrypt the rsa messages using server private key
|
||||
RSADecryptor rsa_dec;
|
||||
@ -52,7 +53,7 @@ Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_cred
|
||||
// send PacketHeader and ServerHandshake over encrypted TCP socket
|
||||
ServerHandshake server_handshake = {0};
|
||||
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, &server_handshake));
|
||||
|
||||
|
||||
25
src/server/request_handlers/Login.c
Normal file
25
src/server/request_handlers/Login.c
Normal 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;
|
||||
}
|
||||
21
src/server/request_handlers/Register.c
Normal file
21
src/server/request_handlers/Register.c
Normal 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;
|
||||
}
|
||||
21
src/server/request_handlers/ServerPublicInfo.c
Normal file
21
src/server/request_handlers/ServerPublicInfo.c
Normal 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;
|
||||
}
|
||||
27
src/server/request_handlers/request_handlers.h
Normal file
27
src/server/request_handlers/request_handlers.h
Normal 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);
|
||||
|
||||
|
||||
31
src/server/request_handlers/send_error.c
Normal file
31
src/server/request_handlers/send_error.c
Normal 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;
|
||||
}
|
||||
9
src/server/request_handlers/template
Normal file
9
src/server/request_handlers/template
Normal 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;
|
||||
}
|
||||
@ -6,12 +6,7 @@
|
||||
#include "config.h"
|
||||
#include "log.h"
|
||||
#include "network/tcp-chat-protocol/v1.h"
|
||||
|
||||
typedef struct ConnectionHandlerArgs {
|
||||
Socket accepted_socket;
|
||||
EndpointIPv4 client_end;
|
||||
u64 session_id;
|
||||
} ConnectionHandlerArgs;
|
||||
#include "server/request_handlers/request_handlers.h"
|
||||
|
||||
static void* handle_connection(void* _args);
|
||||
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){
|
||||
Deferral(32);
|
||||
cstr log_ctx = "Server/MainThread";
|
||||
cstr log_ctx = "MainThread";
|
||||
logInfo(log_ctx, "starting server");
|
||||
logDebug(log_ctx, "parsing config");
|
||||
try_void(parseConfig(config_path));
|
||||
@ -104,100 +99,39 @@ static Result(void) try_handle_connection(ConnectionHandlerArgs* args, cstr log_
|
||||
logInfo(log_ctx, "session closed");
|
||||
);
|
||||
// establish encrypted connection
|
||||
try(conn, p,
|
||||
ClientConnection_accept(
|
||||
_server_credentials,
|
||||
args->accepted_socket,
|
||||
args->client_end,
|
||||
args->session_id
|
||||
)
|
||||
);
|
||||
try(conn, p, ClientConnection_accept(_server_credentials, args));
|
||||
logInfo(log_ctx, "session accepted");
|
||||
|
||||
// handle unauthorized requests
|
||||
bool ahtorized = false;
|
||||
PacketHeader req_header = {0};
|
||||
PacketHeader res_header = {0};
|
||||
while(!ahtorized){
|
||||
sleepMsec(50);
|
||||
// handle requests
|
||||
PacketHeader req_head = {0};
|
||||
PacketHeader res_head = {0};
|
||||
while(true){
|
||||
sleepMsec(20);
|
||||
//TODO: implement some additional check if socket is dead or not
|
||||
|
||||
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req_header));
|
||||
try_void(PacketHeader_validateMagic(&req_header));
|
||||
//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,
|
||||
PROTOCOL_VERSION, PacketType_ErrorMessage, err_buf.size);
|
||||
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &res_header));
|
||||
//TODO: limit ErrorMessage size to fit into EncryptedSocketTCP.internal_buffer_size
|
||||
try_void(EncryptedSocketTCP_send(&conn->sock, err_buf));
|
||||
|
||||
err_complete = true;
|
||||
Return RESULT_ERROR(err_buf.data, true);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
try_void(EncryptedSocketTCP_recvStruct(&conn->sock, &req_head));
|
||||
try_void(PacketHeader_validateMagic(&req_head));
|
||||
|
||||
switch(req_head.type){
|
||||
// send error message and close connection
|
||||
default:
|
||||
try(char* err_msg, p,
|
||||
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;
|
||||
|
||||
// unauthorized requests
|
||||
case_handleRequest(ServerPublicInfo);
|
||||
case_handleRequest(Login);
|
||||
case_handleRequest(Register);
|
||||
// authorized requests
|
||||
}
|
||||
}
|
||||
|
||||
// handle authorized requests
|
||||
while(true){
|
||||
sleepMsec(50);
|
||||
}
|
||||
|
||||
Return RESULT_VOID;
|
||||
}
|
||||
|
||||
@ -16,10 +16,10 @@ Result(ServerCredentials*) ServerCredentials_create(cstr rsa_sk_base64, cstr rsa
|
||||
void ServerCredentials_free(ServerCredentials* cred);
|
||||
|
||||
|
||||
typedef struct ServerMetadata {
|
||||
typedef struct ServerInfo {
|
||||
str name;
|
||||
str description;
|
||||
} ServerMetadata;
|
||||
} ServerInfo;
|
||||
|
||||
|
||||
typedef struct ClientConnection {
|
||||
@ -27,9 +27,17 @@ typedef struct ClientConnection {
|
||||
EndpointIPv4 client_end;
|
||||
Array(u8) session_key;
|
||||
EncryptedSocketTCP sock;
|
||||
bool authorized;
|
||||
} ClientConnection;
|
||||
|
||||
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
|
||||
Socket sock, EndpointIPv4 client_end, u64 session_id);
|
||||
|
||||
typedef struct ConnectionHandlerArgs {
|
||||
Socket accepted_socket;
|
||||
EndpointIPv4 client_end;
|
||||
u64 session_id;
|
||||
} ConnectionHandlerArgs;
|
||||
|
||||
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
|
||||
ConnectionHandlerArgs* args);
|
||||
|
||||
void ClientConnection_close(ClientConnection* conn);
|
||||
Loading…
Reference in New Issue
Block a user