diff options
-rw-r--r-- | chatty.c | 54 | ||||
-rw-r--r-- | chatty.h | 3 | ||||
-rw-r--r-- | protocol.h | 5 | ||||
-rw-r--r-- | server.c | 59 |
4 files changed, 62 insertions, 59 deletions
@@ -17,8 +17,6 @@ #define INPUT_LIMIT 512 // Filepath where user ID is stored #define ID_FILE "_id" -// Import id from ID_FILE -#define IMPORT_ID // Filepath where logged #define LOGFILE "chatty.log" // enable logging @@ -33,12 +31,12 @@ enum { FDS_UNI = 0, // for one-way communication with the server (eg. TextMessag typedef struct { u8 author[AUTHOR_LEN]; ID id; -} Client; -#define CLIENT_FMT "[%s](%lu)" -#define CLIENT_ARG(client) client.author, client.id +} User; +#define USER_FMT "[%s](%lu)" +#define USER_ARG(client) client.author, client.id -// Client used by chatty -global_variable Client user = {0}; +// User used by chatty +global_variable User user = {0}; // Address of chatty server global_variable struct sockaddr_in address; @@ -62,12 +60,12 @@ popup(u32 fg, u32 bg, char* text) // Returns client in clientsArena matching id // Returns user if the id was the user's ID // Returns 0 if nothing was found -Client* -getClientById(Arena* clientsArena, ID id) +User* +getUserByID(Arena* clientsArena, ID id) { if (id == user.id) return &user; - Client* clients = clientsArena->addr; + User* clients = clientsArena->addr; for (u64 i = 0; i < (clientsArena->pos / sizeof(*clients)); i++) { if (clients[i].id == id) @@ -78,8 +76,8 @@ getClientById(Arena* clientsArena, ID id) // Request information of client from fd byd id and add it to clientsArena // Returns pointer to added client -Client* -addClientInfo(Arena* clientsArena, s32 fd, u64 id) +User* +addUserInfo(Arena* clientsArena, s32 fd, u64 id) { // Request information about ID HeaderMessage header = HEADER_INIT(HEADER_TYPE_ID); @@ -93,11 +91,11 @@ addClientInfo(Arena* clientsArena, s32 fd, u64 id) recvAnyMessageType(fd, &header, &introduction_message, HEADER_TYPE_INTRODUCTION); // Add the information - Client* client = ArenaPush(clientsArena, sizeof(*client)); + User* client = ArenaPush(clientsArena, sizeof(*client)); memcpy(client->author, introduction_message.author, AUTHOR_LEN); client->id = id; - loggingf("Got " CLIENT_FMT "\n", CLIENT_ARG((*client))); + loggingf("Got " USER_FMT "\n", USER_ARG((*client))); return client; } @@ -115,7 +113,7 @@ getConnection(struct sockaddr_in* address) } ID -authenticate(Client* user, s32 fd) +authenticate(User* user, s32 fd) { if (user->id) { @@ -149,7 +147,7 @@ authenticate(Client* user, s32 fd) assert(nrecv != -1); assert(nrecv == sizeof(header)); assert(header.type == HEADER_TYPE_ID); - assert(!header.id); + assert(header.id); user->id = header.id; return header.id; } @@ -384,17 +382,17 @@ screen_home(Arena* msgsArena, u32 nmessages, Arena* clientsArena, struct pollfd* HeaderMessage* header = (HeaderMessage*)addr; addr += sizeof(*header); - // Get Client for message - Client* client; + // Get User for message + User* client; switch (header->type) { case HEADER_TYPE_TEXT: case HEADER_TYPE_PRESENCE: - client = getClientById(clientsArena, header->id); + client = getUserByID(clientsArena, header->id); if (!client) { - loggingf("Client not known, requesting from server\n"); - client = addClientInfo(clientsArena, fds[FDS_BI].fd, header->id); + loggingf("User not known, requesting from server\n"); + client = addUserInfo(clientsArena, fds[FDS_BI].fd, header->id); } assert(client); break; @@ -595,8 +593,8 @@ main(int argc, char** argv) loggingf("errno: %d\n", errno); return 1; } - if (!authenticate(&user, unifd) || - !authenticate(&user, bifd)) + loggingf("(%d,%d)\n", unifd, bifd); + if (!authenticate(&user, unifd)) { loggingf("errno: %d\n", errno); return 1; @@ -735,10 +733,10 @@ main(int argc, char** argv) ninput++; // Save header - HeaderMessage header = HEADER_INIT(HEADER_TYPE_TEXT); - void* addr = ArenaPush(&msgsArena, sizeof(header)); - memcpy(addr, &header, sizeof(header)); - header.id = user.id; + HeaderMessage* header = ArenaPush(&msgsArena, sizeof(*header)); + header->version = PROTOCOL_VERSION; + header->type = HEADER_TYPE_TEXT; + header->id = user.id; // Save message TextMessage* sendmsg = ArenaPush(&msgsArena, TEXTMESSAGE_SIZE); @@ -749,7 +747,7 @@ main(int argc, char** argv) ArenaPush(&msgsArena, text_size); memcpy(&sendmsg->text, input, text_size); - sendAnyMessage(fds[FDS_UNI].fd, header, sendmsg); + sendAnyMessage(fds[FDS_UNI].fd, *header, sendmsg); nmessages++; // also clear input @@ -44,6 +44,9 @@ typedef enum { #define global_variable #define internal static +// Enable/Disable saving clients permanently to file +// #define IMPORT_ID + global_variable s32 logfd; u32 @@ -135,6 +135,7 @@ headerTypeString(HeaderType type) case HEADER_TYPE_TEXT: return (u8*)"TextMessage"; case HEADER_TYPE_HISTORY: return (u8*)"HistoryMessage"; case HEADER_TYPE_PRESENCE: return (u8*)"PresenceMessage"; + case HEADER_TYPE_ID: return (u8*)"IDMessage"; case HEADER_TYPE_INTRODUCTION: return (u8*)"IntroductionMessage"; case HEADER_TYPE_ERROR: return (u8*)"ErrorMessage"; default: return (u8*)"Unknown"; @@ -212,7 +213,6 @@ getMessageSize(HeaderType type) { case HEADER_TYPE_ERROR: size = sizeof(ErrorMessage); break; case HEADER_TYPE_HISTORY: size = sizeof(HistoryMessage); break; - case HEADER_TYPE_ID: size = sizeof(HeaderMessage); break; case HEADER_TYPE_INTRODUCTION: size = sizeof(IntroductionMessage); break; case HEADER_TYPE_PRESENCE: size = sizeof(PresenceMessage); break; default: assert(0); @@ -233,7 +233,6 @@ recvAnyMessageType(s32 fd, HeaderMessage* header, void *anyMessage, HeaderType t { case HEADER_TYPE_ERROR: case HEADER_TYPE_HISTORY: - case HEADER_TYPE_ID: case HEADER_TYPE_INTRODUCTION: case HEADER_TYPE_PRESENCE: size = getMessageSize(header->type); @@ -268,7 +267,6 @@ recvAnyMessage(Arena* arena, s32 fd) { case HEADER_TYPE_ERROR: case HEADER_TYPE_HISTORY: - case HEADER_TYPE_ID: case HEADER_TYPE_INTRODUCTION: case HEADER_TYPE_PRESENCE: size = getMessageSize(header->type); @@ -325,7 +323,6 @@ sendAnyMessage(u32 fd, HeaderMessage header, void* anyMessage) { case HEADER_TYPE_ERROR: case HEADER_TYPE_HISTORY: - case HEADER_TYPE_ID: case HEADER_TYPE_INTRODUCTION: case HEADER_TYPE_PRESENCE: size = getMessageSize(header.type); @@ -21,8 +21,6 @@ #define FDS_SIZE (fdsArena.pos / sizeof(struct pollfd)) #define CLIENTS_SIZE (clientsArena.pos / sizeof(Client)) -// Enable/Disable saving clients permanently to file -#define IMPORT_ID // Where to save clients #define CLIENTS_FILE "_clients" // Where to write logs @@ -62,7 +60,7 @@ getClientByID(Client* clients, u32 nclients, ID id) { if (!id) return 0; - for (u32 i = 0; i < nclients - 1; i++) + for (u32 i = 0; i < nclients; i++) { if (clients[i].id == id) return clients + i; @@ -77,7 +75,7 @@ getClientByFD(Client* clients, u32 nclients, s32 fd) { if (fd == -1) return 0; - for (u32 i = 0; i < nclients - 1; i++) + for (u32 i = 0; i < nclients; i++) { if ((clients[i].unifd && clients[i].unifd->fd == fd) || (clients[i].bifd && clients[i].bifd->fd == fd)) @@ -111,7 +109,7 @@ void sendToOthers(Client* clients, u32 nclients, Client* client, ClientFD type, HeaderMessage* header, void* anyMessage) { s32 nsend; - for (u32 i = 0; i < nclients - 1; i ++) + for (u32 i = 0; i < nclients; i ++) { if (clients + i == client) continue; @@ -134,7 +132,7 @@ void sendToAll(Client* clients, u32 nclients, ClientFD type, HeaderMessage* header, void* anyMessage) { s32 nsend; - for (u32 i = 0; i < nclients - 1; i++) + for (u32 i = 0; i < nclients; i++) { if (type == UNIFD) { @@ -195,21 +193,22 @@ authenticate(Arena* clientsArena, s32 clients_file, struct pollfd* pollfd, Heade s32 nrecv = 0; Client* client = 0; + loggingf("authenticate (%d)|" HEADER_FMT "\n", pollfd->fd, HEADER_ARG(header)); + /* Scenario 1: Search for existing client */ if (header.type == HEADER_TYPE_ID) { client = getClientByID((Client*)clientsArena->addr, nclients, header.id); if (!client) { - loggingf("authenticate(%d)|notfound\n", pollfd->fd); + loggingf("authenticate (%d)|notfound\n", pollfd->fd); header.type = HEADER_TYPE_ERROR; ErrorMessage error_message = ERROR_INIT(ERROR_TYPE_NOTFOUND); sendAnyMessage(pollfd->fd, header, &error_message); return 0; } - loggingf("authenticate(%d)|found [%s](%lu)\n", pollfd->fd, client->author, client->id); - header.type = HEADER_TYPE_ERROR; + loggingf("authenticate (%d)|found [%s](%lu)\n", pollfd->fd, client->author, client->id); if (!client->unifd) client->unifd = pollfd; else if(!client->bifd) @@ -217,8 +216,8 @@ authenticate(Arena* clientsArena, s32 clients_file, struct pollfd* pollfd, Heade else assert(0); - ErrorMessage error_message = ERROR_INIT(ERROR_TYPE_SUCCESS); header.type = HEADER_TYPE_ERROR; + ErrorMessage error_message = ERROR_INIT(ERROR_TYPE_SUCCESS); sendAnyMessage(pollfd->fd, header, &error_message); return client; @@ -231,7 +230,7 @@ authenticate(Arena* clientsArena, s32 clients_file, struct pollfd* pollfd, Heade nrecv = recv(pollfd->fd, &message, sizeof(message), 0); if (nrecv != sizeof(message)) { - loggingf("authenticate(%d)|err: %d/%lu bytes\n", pollfd->fd, nrecv, sizeof(message)); + loggingf("authenticate (%d)|err: %d/%lu bytes\n", pollfd->fd, nrecv, sizeof(message)); return 0; } @@ -239,12 +238,20 @@ authenticate(Arena* clientsArena, s32 clients_file, struct pollfd* pollfd, Heade client = ArenaPush(clientsArena, sizeof(*client)); memcpy(client->author, message.author, AUTHOR_LEN); client->id = nclients; + + if (!client->unifd) + client->unifd = pollfd; + else if(!client->bifd) + client->bifd = pollfd; + else + assert(0); + nclients++; #ifdef IMPORT_ID write(clients_file, client, sizeof(*client)); #endif - loggingf("authenticate(%d)|Added [%s](%lu)\n", pollfd->fd, client->author, client->id); + loggingf("authenticate (%d)|Added [%s](%lu)\n", pollfd->fd, client->author, client->id); // Send ID to new client HeaderMessage header = HEADER_INIT(HEADER_TYPE_ID); @@ -256,7 +263,7 @@ authenticate(Arena* clientsArena, s32 clients_file, struct pollfd* pollfd, Heade return client; } - loggingf("authenticate(%d)|Wrong header expected %s or %s\n", pollfd->fd, + loggingf("authenticate (%d)|Wrong header expected %s or %s\n", pollfd->fd, headerTypeString(HEADER_TYPE_INTRODUCTION), headerTypeString(HEADER_TYPE_ID)); return 0; @@ -327,8 +334,9 @@ main(int argc, char** argv) memcpy(fdsAddr, &newpollfd, sizeof(*fds)); newpollfd.fd = -1; + s32 clients_file; #ifdef IMPORT_ID - s32 clients_file = open(CLIENTS_FILE, O_RDWR | O_CREAT | O_APPEND, 0600); + clients_file = open(CLIENTS_FILE, O_RDWR | O_CREAT | O_APPEND, 0600); assert(clients_file != -1); struct stat statbuf; assert(fstat(clients_file, &statbuf) != -1); @@ -341,14 +349,16 @@ main(int argc, char** argv) nclients += statbuf.st_size / sizeof(*clients); // Reset pointers on imported clients - for (u32 i = 0; i < nclients - 1; i++) + for (u32 i = 0; i < nclients; i++) { clients[i].unifd = 0; clients[i].bifd = 0; } } - for (u32 i = 0; i < nclients - 1; i++) + for (u32 i = 0; i < nclients; i++) loggingf("Imported: " CLIENT_FMT "\n", CLIENT_ARG(clients[i])); +#else + clients_file = 0; #endif // Initialize the rest of the fds array @@ -399,10 +409,10 @@ main(int argc, char** argv) } for (u32 conn = FDS_CLIENTS; conn < FDS_SIZE; conn++) - { + { if (!(fds[conn].revents & POLLIN)) continue; if (fds[conn].fd == -1) continue; - loggingf("Message unifd (%d)\n", fds[conn].fd); + loggingf("Message(%d)\n", fds[conn].fd); // We received a message, try to parse the header HeaderMessage header; @@ -413,15 +423,15 @@ main(int argc, char** argv) if (nrecv != sizeof(header)) { client = getClientByFD(clients, nclients, fds[conn].fd); - loggingf(CLIENT_FMT" %d/%lu bytes\n", CLIENT_ARG((*client)), nrecv, sizeof(header)); if (client) { + loggingf(CLIENT_FMT" %d/%lu bytes\n", CLIENT_ARG((*client)), nrecv, sizeof(header)); disconnectAndNotify(clients, nclients, client); loggingf("Disconnected(%lu) [%s]\n", client->id, client->author); } else { - loggingf("Got error from unauntheticated client\n"); + loggingf("Got error/disconnect from unauthenticated client\n"); close(fds[conn].fd); fds[conn].fd = -1; } @@ -445,13 +455,7 @@ main(int argc, char** argv) // Reject connection fds[conn].fd = -1; close(fds[conn].fd); - } - else - { - header.type = HEADER_TYPE_ERROR; - ErrorMessage message = ERROR_INIT(ERROR_TYPE_SUCCESS); - - sendAnyMessage(fds[conn].fd, header, &message); + continue; } } else @@ -471,6 +475,7 @@ main(int argc, char** argv) PresenceMessage message = {.type = PRESENCE_TYPE_CONNECTED}; sendToOthers(clients, nclients, client, UNIFD, &header, &message); } + continue; } switch (header.type) { |