tcp-chat/src/server/ClientConnection.c
2025-11-09 00:49:29 +05:00

61 lines
2.3 KiB
C

#include "server.h"
#include "network/tcp-chat-protocol/v1.h"
void ClientConnection_close(ClientConnection* conn){
if(conn == NULL)
return;
EncryptedSocketTCP_destroy(&conn->sock);
free(conn->session_key.data);
free(conn);
}
Result(ClientConnection*) ClientConnection_accept(ServerCredentials* server_credentials,
Socket sock_tcp, EndpointIPv4 client_end, u64 session_id)
{
Deferral(32);
ClientConnection* conn = (ClientConnection*)malloc(sizeof(ClientConnection));
memset(conn, 0, sizeof(*conn));
bool success = false;
Defer(
if(!success)
ClientConnection_close(conn);
);
conn->client_end = client_end;
conn->session_id = session_id;
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));
// decrypt the rsa messages using server private key
RSADecryptor rsa_dec;
RSADecryptor_construct(&rsa_dec, &server_credentials->rsa_sk);
// receive PacketHeader
PacketHeader packet_header = {0};
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};
try_void(EncryptedSocketTCP_recvStructRSA(&conn->sock, &rsa_dec, &client_handshake));
// use received session key
memcpy(conn->session_key.data, client_handshake.session_key, conn->session_key.size);
EncryptedSocketTCP_changeKey(&conn->sock, conn->session_key);
// send PacketHeader and ServerHandshake over encrypted TCP socket
ServerHandshake server_handshake = {0};
ServerHandshake_construct(&server_handshake, &packet_header,
session_id);
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &packet_header));
try_void(EncryptedSocketTCP_sendStruct(&conn->sock, &server_handshake));
success = true;
Return RESULT_VALUE(p, conn);
}