Improve relaying message in server
This commit is contained in:
parent
9c1479bb73
commit
062028e4e1
1 changed files with 32 additions and 35 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue