Improve relaying message in server

This commit is contained in:
Night Kaly 2024-09-18 08:40:05 +01:00
parent 9c1479bb73
commit 062028e4e1
Signed by: night0721
GPG key ID: 957D67B8DB7A119B

View file

@ -2,6 +2,7 @@
#include "util.h" #include "util.h"
#include "config.h" #include "config.h"
#include "notification.h" #include "notification.h"
#include "server/server.h"
typedef struct client_t { typedef struct client_t {
int fd; /* File descriptor for client socket */ int fd; /* File descriptor for client socket */
@ -20,7 +21,6 @@ thread_t threads[MAX_THREADS];
int num_thread = 0; int num_thread = 0;
void *thread_worker(void *arg); void *thread_worker(void *arg);
int set_nonblocking(int fd);
/* /*
* Authenticate client before starting communication * Authenticate client before starting communication
@ -34,7 +34,7 @@ int authenticate_client(int clientfd, uint8_t *username)
/* Sending fake signature as structure requires it */ /* Sending fake signature as structure requires it */
uint8_t *fake_sig = create_signature(NULL, 0, NULL); uint8_t *fake_sig = create_signature(NULL, 0, NULL);
packet *auth_pkt = create_packet(1, ZSM_TYP_AUTH, CHALLENGE_SIZE, packet_t *auth_pkt = create_packet(1, ZSM_TYP_AUTH, CHALLENGE_SIZE,
challenge, fake_sig); challenge, fake_sig);
if (send_packet(auth_pkt, clientfd) != ZSM_STA_SUCCESS) { if (send_packet(auth_pkt, clientfd) != ZSM_STA_SUCCESS) {
/* fd already closed */ /* fd already closed */
@ -45,7 +45,7 @@ int authenticate_client(int clientfd, uint8_t *username)
} }
free(fake_sig); free(fake_sig);
packet client_auth_pkt; packet_t client_auth_pkt;
int status; int status;
if ((status = recv_packet(&client_auth_pkt, clientfd, ZSM_TYP_AUTH) if ((status = recv_packet(&client_auth_pkt, clientfd, ZSM_TYP_AUTH)
!= ZSM_STA_SUCCESS)) { != ZSM_STA_SUCCESS)) {
@ -62,7 +62,7 @@ int authenticate_client(int clientfd, uint8_t *username)
free(client_auth_pkt.data); free(client_auth_pkt.data);
goto failure; goto failure;
} else { } else {
packet *ok_pkt = create_packet(ZSM_STA_AUTHORISED, ZSM_TYP_INFO packet_t *ok_pkt = create_packet(ZSM_STA_AUTHORISED, ZSM_TYP_INFO
, 0, NULL, NULL); , 0, NULL, NULL);
send_packet(ok_pkt, clientfd); send_packet(ok_pkt, clientfd);
free_packet(ok_pkt); free_packet(ok_pkt);
@ -70,7 +70,7 @@ int authenticate_client(int clientfd, uint8_t *username)
return ZSM_STA_SUCCESS; return ZSM_STA_SUCCESS;
} }
failure:; failure:;
packet *error_pkt = create_packet(ZSM_STA_UNAUTHORISED, ZSM_TYP_ERROR, packet_t *error_pkt = create_packet(ZSM_STA_UNAUTHORISED, ZSM_TYP_ERROR,
0, NULL, create_signature(NULL, 0, NULL)); 0, NULL, create_signature(NULL, 0, NULL));
send_packet(error_pkt, clientfd); send_packet(error_pkt, clientfd);
@ -88,15 +88,27 @@ void signal_handler(int signal)
case SIGABRT: case SIGABRT:
case SIGINT: case SIGINT:
case SIGTERM: case SIGTERM:
notify_uninit();
error(1, "Shutdown signal received"); error(1, "Shutdown signal received");
break; break;
} }
} }
int get_clientfd(uint8_t *username)
{
for (int i = 0; i < MAX_THREADS; i++) {
thread_t thread = threads[i];
for (int j = 0; j < thread.num_clients; j++) {
client_t client = thread.clients[j];
if (strncmp(client.username, username, MAX_NAME) == 0) {
return client.fd;
}
}
}
return -1;
}
/* /*
* Takes thread_t as argument to use its epoll instance to wait new messages * Takes thread_t as argument to use its epoll instance to wait new pakcets
* Thread worker to relay messages * Thread worker to relay packets
*/ */
void *thread_worker(void *arg) void *thread_worker(void *arg)
{ {
@ -112,25 +124,22 @@ void *thread_worker(void *arg)
client_t *client = (client_t *) events[i].data.ptr; client_t *client = (client_t *) events[i].data.ptr;
if (events[i].events & EPOLLIN) { if (events[i].events & EPOLLIN) {
/* handle message */ /* Handle packet */
packet pkt; packet_t pkt;
packet *verified_pkt = verify_packet(&pkt, client->fd); if (verify_packet(&pkt, client->fd) == 0) {
if (verified_pkt == NULL) {
error(0, "Error verifying packet"); error(0, "Error verifying packet");
} }
/* Message relay */ /* Message relay */
uint8_t to[MAX_NAME]; uint8_t to[MAX_NAME];
memcpy(to, verified_pkt->data + MAX_NAME, MAX_NAME); memcpy(to, pkt.data + MAX_NAME, MAX_NAME);
if (to[0] != '\0') {
for (int i = 0; i < MAX_THREADS; i++) { int fd = get_clientfd(to);
thread_t thread = threads[i]; if (fd != -1) {
for (int j = 0; j < thread.num_clients; j++) { error(0, "Relaying packet to %s", to);
client_t client = thread.clients[j]; send_packet(&pkt, fd);
if (strcmp(client.username, to) == 0) { } else {
error(0, "Relaying message to %s", client.username); error(0, "%s not found", to);
send_packet(verified_pkt, client.fd);
}
} }
} }
} }
@ -143,10 +152,7 @@ int main()
if (sodium_init() < 0) { if (sodium_init() < 0) {
error(1, "Error initializing libsodium"); error(1, "Error initializing libsodium");
} }
/* Init libnotify with app name */
if (notify_init("zsm") < 0) {
error(1, "Error initializing libnotify");
}
signal(SIGPIPE, signal_handler); signal(SIGPIPE, signal_handler);
signal(SIGABRT, signal_handler); signal(SIGABRT, signal_handler);
signal(SIGINT, signal_handler); signal(SIGINT, signal_handler);
@ -235,15 +241,6 @@ int main()
continue; continue;
} }
/* To use EPOLLET, an nonblocking fd is required */
/*
if (set_nonblocking(clientfd) == -1) {
perror("Failed to set client socket to non-blocking");
close(clientfd);
continue;
}
*/
/* Add the new client to the thread's epoll instance */ /* Add the new client to the thread's epoll instance */
struct epoll_event event; struct epoll_event event;
event.data.ptr = client; event.data.ptr = client;