diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 2e901b7..0000000 --- a/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -.bash_history -.bashrc -.config/ -.gdb_history -.gdbinit -.idea/ -.inputrc -.viminfo -.vscode/ -server -client -*.o -quine -a.out diff --git a/Makefile b/Makefile index 457ee0a..bfb50de 100644 --- a/Makefile +++ b/Makefile @@ -12,20 +12,20 @@ TMP := $(shell mktemp) all: $(ERROR) $(CHALLENGE) $(RANDOM) $(SOCKETS) $(CLIENT) $(SERVER) -$(SERVER): server.c challenges.c errors.c include/errors.h include/challenges.h include/server.h include/challengesLib.h +$(SERVER): server.c challenges.c errors.c sockets.c include/errors.h include/challenges.h include/server.h include/challengesLib.h include/sockets.h $(CC) $(CCFLAGS) server.c -o server challenges.o errors.o random.o sockets.o -lm objcopy --add-section .RUN_ME="$(TMP)" --set-section-flags .mydata=noload,readonly server strip --strip-debug server rm "$(TMP)" -$(CLIENT): client.c errors.c include/errors.h include/client.h +$(CLIENT): client.c errors.c sockets.c include/errors.h include/client.h include/sockets.h $(CC) $(CCFLAGS) client.c -o client errors.o sockets.o %.o: %.c $(CC) $(CCFLAGS) -I./include -c $< clean: - rm -rf $(ERROR) $(CHALLENGE) $(CLIENT) $(SERVER) $(RANDOM) $(SOCKETS) PVS-Studio.log report.tasks strace_out + rm -rf $(ERROR) $(CHALLENGE) $(CLIENT) $(SERVER) $(RANDOM) $(SOCKETS) test: pvs-studio-analyzer trace -- make @@ -33,4 +33,7 @@ test: plog-converter -a '64:1,2,3;GA:1,2,3;OP:1,2,3' -t tasklist -o report.tasks PVS-Studio.log cppcheck --quiet --enable=all --force --inconclusive . -.PHONY: all clean test +cleanTest: + rm -rf PVS-Studio.log report.tasks strace_out + +.PHONY: all clean test cleanTest diff --git a/README.md b/README.md index 0406afd..c966788 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ -# BSSolver +# BCSSolver -BCSSocket (Bottler Client-Server Socket) es un sistema que... +BCSSocket (Bottler Client-Server Socket) -## Table de contenidos -* [Requisitos](#requisitos) -* [Compilación](#compilación) -* [Ejecución](#ejecución) -* [Testeos](#tests) +## Tabla de contenidos +- [Requisitos ](#requisitos-) +- [Compilación ](#compilación-) +- [Ejecución ](#ejecución-) +- [Testeos ](#testeos-) +- [Limpieza ](#limpieza-) ## Requisitos @@ -39,7 +40,11 @@ y en otra terminal ./client ``` -Debe notar que el `server` usará el puerto 8080 de localhost por lo que si tiene algún otro servidor en ese puerto debe cerrarlo antes de correrlo. +Debe notar que el `server` usará el puerto 8080 de localhost (por default) por lo que si tiene algún otro servidor en ese puerto debe cerrarlo antes de correrlo. Asimismo, si usted quiere modificar este puerto y/o la dirección del servidor lo puede hacer mediante: + +```bash +./server -a ${address} -p ${port} +``` ## Testeos @@ -61,7 +66,20 @@ y en otra terminal valgrind ./client ``` +## Limpieza +Si desea borrar los archivos creados luego de la compilación debe correr: + +```bash +make clean +``` + +Note que si, además, quiere borrar el output de los tests (de PVS-Studio específicamente), lo puede hacer con: + +```bash +make cleanTest +``` + # Autores - Barmasch, Juan Martín (61033) - Bellver, Ezequiel (61268) -- Lo Coco, Santiago (61301) \ No newline at end of file +- Lo Coco, Santiago (61301) diff --git a/challenges.c b/challenges.c index bcc116e..f2ad9e8 100644 --- a/challenges.c +++ b/challenges.c @@ -16,8 +16,7 @@ char genChallenge(FILE * stream, char ** output, challenge_t challenge) { if (getline(output, &linecap, stream) < 0) printSystemError("Challenges: getline()"); - int ans = strcmp(*output, challenge.flag); - return !ans; + return !strcmp(*output, challenge.flag); } void writeChallenge() { @@ -77,23 +76,17 @@ void quineChallenge() { printf("\nENTER para reintentar.\n"); } -void gdbme(char * output) { - if (getpid() == 0x12345678) { - *output = 1; - } - else *output = 0; -} - -void gdbChallenge() { - char gdbOutput; - gdbme(&gdbOutput); - - if (gdbOutput) +void gdbme() { + if (getpid() == MAGIC_VAL) printf("La respuesta es gdb_rules\n"); else printf("ENTER para reintentar.\n"); } +void gdbChallenge() { + gdbme(); +} + void boxMuller(double * normal) { double random1 = getUniform(1); double random2 = getUniform(1); diff --git a/challenges.md b/challenges.md new file mode 100644 index 0000000..caf0b39 --- /dev/null +++ b/challenges.md @@ -0,0 +1,56 @@ +# CHALLENGES: + +- entendido +- itba +- M4GFKZ289aku +- fk3wfLCm3QvS +- too_easy +- .RUN_ME +- K5n2UFfpFMUN +- BUmyYq5XxXGt +- u^v +- chin_chu_lan_cha +- gdb_rules +- normal + +# EASTER EGGS: + +I) `strings server` +``` + _______________________ +< ESTO ES UN EASTER_EGG > + ----------------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\ + ||----w | + || || +``` + +II) `cat /tmp/hidden` + +``` +QUE CURIOSO +``` + +III) `objdump -x server` --> `objdump -d --section .text server` + +``` +__L +D_A +N_I +I_N +R_E +G_G +L__ +A_S +V_E +``` +Leyendo de abajo para arriba en cada columna: + +``` +VALGRIND ES GENIAL +``` +(aunque no usamos valgrind pero: `valgrind ./server > /dev/null` también arroja el resultado) + + diff --git a/client.c b/client.c index 32d874d..98dd486 100644 --- a/client.c +++ b/client.c @@ -3,16 +3,21 @@ #include "include/client.h" int main(int argc, char *argv[]) { - int fd; - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - printSystemError("User: socket()"); + int fd = createSocket(); struct sockaddr_in serv_addr; setSockAddress(argc, argv, &serv_addr); - if (connect(fd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) - printSystemError("User: connect()"); + connectToSocket(fd, &serv_addr); + processAndSendInput(fd); + + closeSocket(fd); + + return EXIT_SUCCESS; +} + +void processAndSendInput(int fd) { char input[MAX_LEN] = {0}; int readChars; while ((readChars = read(STDIN_FILENO, input, MAX_LEN - 1)) != 0) { @@ -23,8 +28,4 @@ int main(int argc, char *argv[]) { if (write(fd, input, readChars) < 0) printSystemError("User: write()"); } - - close(fd); - - return EXIT_SUCCESS; } \ No newline at end of file diff --git a/include/challenges.h b/include/challenges.h index ae657b1..b54792d 100644 --- a/include/challenges.h +++ b/include/challenges.h @@ -16,6 +16,7 @@ #define UPPER 2 #define LOWER 1 #define M_PI 3.14159265358979323846 +#define MAGIC_VAL 0x12345678 typedef struct challenge_t { char * message; diff --git a/include/challengesLib.h b/include/challengesLib.h index 01c942d..9f7f5ec 100644 --- a/include/challengesLib.h +++ b/include/challengesLib.h @@ -22,7 +22,7 @@ conviene usar cada uno?", "itba\n", NULL}, que usan para mandar las respuestas? ¿Por qué?", "M4GFKZ289aku\n", NULL}, {"EBADF...", "¿Qué útil abstracción es utilizada para comunicarse con sockets? ¿se puede \ utilizar read(2) y write(2) para operar?", "fk3wfLCm3QvS\n", writeChallenge}, - {"respuesta = strings:269", "¿Cómo garantiza TCP que los paquetes llegan en orden y no se \ + {"respuesta = strings:250", "¿Cómo garantiza TCP que los paquetes llegan en orden y no se \ pierden?", "too_easy\n", NULL}, {".data .bss .comment ? .shstrtab .symtab .strtab", "Un servidor suele crear un nuevo proceso \ o thread para atender las conexiones entrantes. ¿Qué conviene más?", ".RUN_ME\n", NULL}, @@ -39,13 +39,5 @@ entonces\ny = ", "sockets es un mecanismo de IPC. ¿Qué es más eficiente entre }; char too_easy = 'a'; -char * easter_egg1 = " _______________________\n\ -< ESTO ES UN EASTER_EGG >\n\ - -----------------------\n\ - \\ ^__^\n\ - \\ (oo)\\_______\n\n\ - (__)\\ )\\/\\\n\ - ||----w |\n\ - || ||\n"; #endif \ No newline at end of file diff --git a/include/client.h b/include/client.h index 4918f2f..4fb89e1 100644 --- a/include/client.h +++ b/include/client.h @@ -4,7 +4,6 @@ #define _POSIX_C_SOURCE 200809L #include -#include #include #include #include @@ -14,4 +13,6 @@ #define MAX_LEN 100 +void processAndSendInput(int fd); + #endif \ No newline at end of file diff --git a/include/server.h b/include/server.h index 4b4059f..663a83e 100644 --- a/include/server.h +++ b/include/server.h @@ -4,8 +4,6 @@ #define _POSIX_C_SOURCE 200809L #include -#include -#include #include #include #include @@ -17,7 +15,6 @@ #include "sockets.h" #define MAX_LEN 100 -#define MAX_PEND_REQ 3 #define TIME_SLEEP 2 void startChallenge(); diff --git a/include/sockets.h b/include/sockets.h index 53f45e1..5ed0899 100644 --- a/include/sockets.h +++ b/include/sockets.h @@ -13,7 +13,13 @@ #define PORT 8080 #define ADDRESS "127.0.0.1" +#define MAX_PEND_REQ 3 +int createSocket(); +void setSockOptions(int fd); void setSockAddress(int argc, char *argv[], struct sockaddr_in * address); +int bindAndGetSocket(int fd, struct sockaddr_in *address); +void connectToSocket(int fd, struct sockaddr_in *address); +void closeSocket(int fd); #endif \ No newline at end of file diff --git a/server.c b/server.c index 976db84..2c62808 100644 --- a/server.c +++ b/server.c @@ -3,34 +3,20 @@ #include "include/server.h" int main(int argc, char *argv[]) { - int fd; - if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) - printSystemError("Server: socket()"); - - int opt = 1; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) - printSystemError("Server: setsockopt()"); + int fd = createSocket(); + setSockOptions(fd); struct sockaddr_in address; setSockAddress(argc, argv, &address); - - if (bind(fd, (struct sockaddr *) &address, sizeof(address)) < 0) - printSystemError("Server: bind()"); - if (listen(fd, MAX_PEND_REQ) < 0) - printSystemError("Server: listen()"); - - int addrlen = sizeof(address), fdAux; - if ((fdAux = accept(fd, (struct sockaddr *) &address, (socklen_t *) &addrlen)) < 0) - printSystemError("Server: accept()"); + int fdAux = bindAndGetSocket(fd, &address); if (setvbuf(stdout, NULL, _IONBF, 0) != 0) printSystemError("Server: setvbuf()"); startChallenge(fdAux); - close(fdAux); - close(fd); + closeSocket(fd); return EXIT_SUCCESS; } @@ -59,8 +45,10 @@ void startChallenge(int fd) { printf("\033[1;1H\033[2J"); printf("Felicitaciones, finalizaron el juego. Ahora deberán implementar el servidor que se comporte como el servidor provisto\n"); - if (stream != NULL) - fclose(stream); + if (stream != NULL) { + if (fclose(stream) == EOF) + printSystemError("Server: fclose()"); + } return; } diff --git a/sockets.c b/sockets.c index bc501cd..7aa66e9 100644 --- a/sockets.c +++ b/sockets.c @@ -2,29 +2,62 @@ // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com #include "include/sockets.h" +int createSocket() { + int fd; + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + printSystemError("Sockets: socket()"); + return fd; +} + +void setSockOptions(int fd) { + int opt = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) + printSystemError("Sockets: setsockopt()"); +} + +int bindAndGetSocket(int fd, struct sockaddr_in *address) { + if (bind(fd, (struct sockaddr *) address, sizeof(*address)) < 0) + printSystemError("Sockets: bind()"); + + if (listen(fd, MAX_PEND_REQ) < 0) + printSystemError("Sockets: listen()"); + + int addrlen = sizeof(*address), fdAux; + if ((fdAux = accept(fd, (struct sockaddr *) address, (socklen_t *) &addrlen)) < 0) + printSystemError("Sockets: accept()"); + + return fdAux; +} + +void connectToSocket(int fd, struct sockaddr_in *address) { + if (connect(fd, (struct sockaddr *) address, sizeof(*address)) < 0) + printSystemError("Sockets: connect()"); +} + +void closeSocket(int fd) { + if (close(fd) < 0) + printSystemError("Sockets: close()"); +} + void setSockAddress(int argc, char *argv[], struct sockaddr_in * address) { address->sin_family = AF_INET; - - if (argc == 1) { - address->sin_addr.s_addr = inet_addr(ADDRESS); - address->sin_port = htons(PORT); - } + address->sin_addr.s_addr = inet_addr(ADDRESS); + address->sin_port = htons(PORT); int opt; + opterr = 0; while ((opt = getopt(argc, argv, "a:p:")) != -1) { - switch (opt) { - case 'a': - if (optarg[0] == '-') - printError("Usage: server [-a address] [-p port]\n"); - address->sin_addr.s_addr = inet_addr(optarg); - break; - case 'p': - if (optarg[0] == '-') - printError("Usage: server [-a address] [-p port]\n"); - address->sin_port = htons(atoi(optarg)); - break; - default: + if (optarg[0] == '-') printError("Usage: server [-a address] [-p port]\n"); + switch (opt) { + case 'a': + address->sin_addr.s_addr = inet_addr(optarg); + break; + case 'p': + address->sin_port = htons(atoi(optarg)); + break; + default: + printError("Usage: server [-a address] [-p port]\n"); } } } \ No newline at end of file