From 4fb1542b48537b723d56a7d1a9225e5b8a5b83ff Mon Sep 17 00:00:00 2001 From: nick-kramer117 Date: Wed, 15 Feb 2023 09:09:50 -0400 Subject: [PATCH] Initial Comit... --- Makefile | 6 + client_NT117.c | 194 ++++++++++++++++++++++++++++++++ server_NT117.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 497 insertions(+) create mode 100644 Makefile create mode 100644 client_NT117.c create mode 100644 server_NT117.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6ada4f4 --- /dev/null +++ b/Makefile @@ -0,0 +1,6 @@ +compile: + gcc -Wall -g3 -fsanitize=address -pthread server_NT117.c -o server_NT117 + gcc -Wall -g3 -fsanitize=address -pthread client_NT117.c -o client_NT117 +FLAGS = -L /lib64 +LIBS = -lusb-1.0 -l pthread + diff --git a/client_NT117.c b/client_NT117.c new file mode 100644 index 0000000..578d6d1 --- /dev/null +++ b/client_NT117.c @@ -0,0 +1,194 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LENGTH 2048 + +// Global variables +volatile sig_atomic_t flag = 0; +int sockfd = 0; +char name[32]; + +void str_overwrite_stdout() +{ + printf("%s", "[>] "); + fflush(stdout); +} + +void str_trim_lf (char* arr, int length) +{ + int i; + for (i = 0; i < length; i++) + { + if (arr[i] == '\n') + { + arr[i] = '\0'; + break; + } + } +} + +void catch_ctrl_c_and_exit(int sig) +{ + flag = 1; +} + +void send_msg_handler() +{ + char message[LENGTH] = {}; + char buffer[LENGTH + 32] = {}; + + while(1) + { + str_overwrite_stdout(); + fgets(message, LENGTH, stdin); + str_trim_lf(message, LENGTH); + + if (strcmp(message, "exit") == 0) + { + break; + } + else + { + sprintf(buffer, "%s: %s\n", name, message); + send(sockfd, buffer, strlen(buffer), 0); + } + + bzero(message, LENGTH); + bzero(buffer, LENGTH + 32); + } + + catch_ctrl_c_and_exit(2); +} + +void recv_msg_handler() +{ + char message[LENGTH] = {}; + + while(1) + { + int receive = recv(sockfd, message, LENGTH, 0); + + if(receive > 0) + { + printf("%s", message); + str_overwrite_stdout(); + } + else if(receive == 0) + { + break; + } + else + { + // -1 + } + memset(message, 0, sizeof(message)); + } +} + +int main(int argc, char **argv) +{ + // Standard parameters + char *ip = "127.0.0.1"; + int port = 10117; + char *pswd = "117"; + + if(argc == 4) + { + printf("[+] - Set User setting.\n"); + ip = argv[1]; + port = atoi(argv[2]); + pswd = argv[3]; + } + else if(argc == 3) + { + printf("[+] - Set User setting.\n"); + ip = argv[1]; + port = atoi(argv[2]); + } + else if(argc == 2) + { + printf("[+] - Set User setting.\n"); + ip = argv[1]; + } + else if(argc > 4) + { + printf("[!] - Error ENTER KEY!\n"); + return EXIT_FAILURE; + } + else + { + printf("[+] - Set default setting.\n"); + } + + printf("Server IP address: %s \n", ip); + printf("Server Port: %d \n", port); + printf("Server Password: %s \n", pswd); + + signal(SIGINT, catch_ctrl_c_and_exit); + + printf("[?] - Please enter your name: "); + fgets(name, 32, stdin); + str_trim_lf(name, strlen(name)); + + if(strlen(name) > 32 || strlen(name) < 2) + { + printf("[!] - Name must be less than 30 and more than 2 characters!\n"); + return EXIT_FAILURE; + } + + struct sockaddr_in server_addr; + + /* Socket settings */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + server_addr.sin_family = AF_INET; + server_addr.sin_addr.s_addr = inet_addr(ip); + server_addr.sin_port = htons(port); + + + // Connect to Server + int err = connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); + if(err == -1) + { + printf("[!] - ERROR: connect!\n"); + return EXIT_FAILURE; + } + + // Send name + send(sockfd, name, 32, 0); + + printf("--=== WELCOME TO THE CHAT NT117 (Client)===--\n"); + + pthread_t send_msg_thread; + if(pthread_create(&send_msg_thread, NULL, (void *) send_msg_handler, NULL) != 0) + { + printf("[!] - ERROR: pthread!\n"); + return EXIT_FAILURE; + } + + pthread_t recv_msg_thread; + if(pthread_create(&recv_msg_thread, NULL, (void *) recv_msg_handler, NULL) != 0) + { + printf("[!] - ERROR: pthread!\n"); + return EXIT_FAILURE; + } + + while(1) + { + if(flag) + { + printf("[*] - Exit...\n"); + break; + } + } + + close(sockfd); + return EXIT_SUCCESS; +} diff --git a/server_NT117.c b/server_NT117.c new file mode 100644 index 0000000..971090e --- /dev/null +++ b/server_NT117.c @@ -0,0 +1,297 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_CLIENTS 100 +#define BUFFER_SZ 2048 + +static _Atomic unsigned int cli_count = 0; +static int uid = 10; + +// Client structure +typedef struct +{ + struct sockaddr_in address; + int sockfd; + int uid; + char name[32]; +} client_t; + +client_t *clients[MAX_CLIENTS]; + +pthread_mutex_t clients_mutex = PTHREAD_MUTEX_INITIALIZER; + +void str_overwrite_stdout() +{ + printf("\r%s", "> "); + fflush(stdout); +} + +void str_trim_lf (char* arr, int length) +{ + int i; + for (i = 0; i < length; i++) + { + if (arr[i] == '\n') + { + arr[i] = '\0'; + break; + } + } +} + +void print_client_addr(struct sockaddr_in addr) +{ + printf("%d.%d.%d.%d", + addr.sin_addr.s_addr & 0xff, + (addr.sin_addr.s_addr & 0xff00) >> 8, + (addr.sin_addr.s_addr & 0xff0000) >> 16, + (addr.sin_addr.s_addr & 0xff000000) >> 24); +} + +// Add clients to queue +void queue_add(client_t *cl) +{ + pthread_mutex_lock(&clients_mutex); + + for(int i=0; i < MAX_CLIENTS; ++i) + { + if(!clients[i]) + { + clients[i] = cl; + break; + } + } + + pthread_mutex_unlock(&clients_mutex); +} + +// Remove clients to queue +void queue_remove(int uid) +{ + pthread_mutex_lock(&clients_mutex); + + for(int i=0; i < MAX_CLIENTS; ++i) + { + if(clients[i]) + { + if(clients[i]->uid == uid) + { + clients[i] = NULL; + break; + } + } + } + + pthread_mutex_unlock(&clients_mutex); +} + +// Send message to all clients except sender +void send_message(char *s, int uid) +{ + pthread_mutex_lock(&clients_mutex); + + for(int i=0; iuid != uid) + { + if(write(clients[i]->sockfd, s, strlen(s)) < 0) + { + perror("[!] - ERROR: write to descriptor failed"); + break; + } + } + } + } + + pthread_mutex_unlock(&clients_mutex); +} + +// Handle all communication with the client +void *handle_client(void *arg) +{ + char buff_out[BUFFER_SZ]; + char name[32]; + int leave_flag = 0; + + cli_count++; + client_t *cli = (client_t *)arg; + + // Name + if(recv(cli->sockfd, name, 32, 0) <= 0 || strlen(name) < 2 || strlen(name) >= 32-1) + { + printf("[!] - Didn't enter the name.\n"); + leave_flag = 1; + } + else + { + strcpy(cli->name, name); + sprintf(buff_out, "%s has joined\n", cli->name); + printf("%s", buff_out); + send_message(buff_out, cli->uid); + } + + bzero(buff_out, BUFFER_SZ); + + while(1) + { + if (leave_flag) + { + break; + } + + int receive = recv(cli->sockfd, buff_out, BUFFER_SZ, 0); + if (receive > 0) + { + if(strlen(buff_out) > 0) + { + send_message(buff_out, cli->uid); + + str_trim_lf(buff_out, strlen(buff_out)); + printf("%s -> %s\n", buff_out, cli->name); + } + } + else if (receive == 0 || strcmp(buff_out, "exit") == 0) + { + sprintf(buff_out, "%s has left\n", cli->name); + printf("%s", buff_out); + send_message(buff_out, cli->uid); + leave_flag = 1; + } + else + { + printf("[!] - ERROR: -1\n"); + leave_flag = 1; + } + + bzero(buff_out, BUFFER_SZ); + } + + // Delete client from queue and yield thread + close(cli->sockfd); + queue_remove(cli->uid); + free(cli); + cli_count--; + pthread_detach(pthread_self()); + + return NULL; +} + +int main(int argc, char **argv) +{ + // Standard parameters + char *ip = "127.0.0.1"; + int port = 10117; + char *pswd = "117"; + + if(argc == 4) + { + printf("[+] - Set Administrator setting.\n"); + ip = argv[1]; + port = atoi(argv[2]); + pswd = argv[3]; + } + else if(argc == 3) + { + printf("[+] - Set Administrator setting.\n"); + ip = argv[1]; + port = atoi(argv[2]); + } + else if(argc == 2) + { + printf("[+] - Set Administrator setting.\n"); + ip = argv[1]; + } + else if(argc > 4) + { + printf("[!] - Error ENTER KEY!\n"); + return EXIT_FAILURE; + } + else + { + printf("[+] - Set default setting.\n"); + } + + printf("Server IP address: %s \n", ip); + printf("Server Port: %d \n", port); + printf("Server Password: %s \n", pswd); + + int option = 1; + int listenfd = 0, connfd = 0; + struct sockaddr_in serv_addr; + struct sockaddr_in cli_addr; + pthread_t tid; + + // Socket settings + listenfd = socket(AF_INET, SOCK_STREAM, 0); + serv_addr.sin_family = AF_INET; + serv_addr.sin_addr.s_addr = inet_addr(ip); + serv_addr.sin_port = htons(port); + + // Ignore pipe signals + signal(SIGPIPE, SIG_IGN); + + if(setsockopt(listenfd, SOL_SOCKET,(SO_REUSEPORT | SO_REUSEADDR),(char*)&option,sizeof(option)) < 0) + { + perror("[!] - ERROR: setsockopt failed!"); + return EXIT_FAILURE; + } + + // Bind + if(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) + { + perror("[!] - ERROR: Socket binding failed!"); + return EXIT_FAILURE; + } + + // Listen + if (listen(listenfd, 10) < 0) + { + perror("[!] - ERROR: Socket listening failed!"); + return EXIT_FAILURE; + } + + printf("--=== WELCOME TO THE CHAT NT117 (Server) ===--\n"); + + while(1) + { + socklen_t clilen = sizeof(cli_addr); + connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &clilen); + + // Check if max clients is reached + if((cli_count + 1) == MAX_CLIENTS) + { + printf("[?] - Max clients reached. Rejected: "); + print_client_addr(cli_addr); + printf(":%d\n", cli_addr.sin_port); + close(connfd); + continue; + } + + // Client settings + client_t *cli = (client_t *)malloc(sizeof(client_t)); + cli->address = cli_addr; + cli->sockfd = connfd; + cli->uid = uid++; + + // Add client to the queue and fork thread + queue_add(cli); + pthread_create(&tid, NULL, &handle_client, (void*)cli); + + // Reduce CPU usage + sleep(1); + } + + return EXIT_SUCCESS; +}