aboutsummaryrefslogtreecommitdiff
path: root/server.c
diff options
context:
space:
mode:
Diffstat (limited to 'server.c')
-rw-r--r--server.c220
1 files changed, 98 insertions, 122 deletions
diff --git a/server.c b/server.c
index 02c9f5a..8592b10 100644
--- a/server.c
+++ b/server.c
@@ -1,7 +1,5 @@
/* The server recieves connections and passes files to the clients
*/
-#include <server-connection.h>
-
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -19,18 +17,39 @@
#include <sds/sds.h>
#include <util.h>
-#define MAX_LEN_COMMAND 16
-#define COMMAND_FORMAT ": %16s"
+#include <server-connection.h>
+#include <server-cli.h>
-void freeVhosts(sds **vhosts, int argc) {
- for (int i = 1; i < argc; i++) {
- sdsfreesplitres(vhosts[i-1], 3);
- }
- free(vhosts);
+int createCommunicationSocket(const char* ip, const char* port) {
+ int fd_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
+ herr(fd_socket, "socket");
+
+ int aton_status = 0;
+ struct sockaddr_in sa_socket = {
+ .sin_family = AF_INET,
+ .sin_port = atop(port),
+ .sin_addr = aton(ip, &aton_status),
+ };
+ herr(aton_status, "inet_aton");
+
+ // Reuse address when in TIME_WAIT state, after listening socket was closed
+ // https://stackoverflow.com/a/10651048/12036073
+ // https://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states#comment951880_173543
+ int true = 1;
+ herr(setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)), "setsockopt");
+
+ herr(bind(fd_socket, (struct sockaddr*)&sa_socket, sizeof(struct sockaddr_in)), "bind");
+
+ herr(listen(fd_socket, 50), "listen");
+
+ return fd_socket;
}
-int streq(const char* first, const char* second) {
- return strcmp(first, second) == 0;
+void freeVhosts(sds **vhosts, int vhostsc) {
+ for (int i = 1; i < vhostsc; i++) {
+ sdsfreesplitres(vhosts[i], 3);
+ }
+ free(vhosts);
}
int acceptConnections = 1;
@@ -52,135 +71,92 @@ int main(int argc, char* argv[]) {
/*
* Create socket for accepting connections
*/
- int fd_socket;
- herr(fd_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0), "socket");
-
- struct sockaddr_in sa_socket = {
- .sin_family = AF_INET,
- .sin_port = inet_atop("8080"),
- };
- herr(inet_aton("127.0.0.1", &sa_socket.sin_addr.s_addr), "inet_aton");
-
- // Reuse address when in TIME_WAIT state, after listening socket was closed
- // https://stackoverflow.com/a/10651048/12036073
- // https://superuser.com/questions/173535/what-are-close-wait-and-time-wait-states#comment951880_173543
- int true = 1;
- herr(setsockopt(fd_socket, SOL_SOCKET, SO_REUSEADDR, &true, sizeof(int)), "setsockopt");
-
- herr(bind(fd_socket, (struct sockaddr*)&sa_socket, sizeof(struct sockaddr_in)), "bind");
-
- herr(listen(fd_socket, 50), "listen");
+ int fd_socket = createCommunicationSocket("127.0.0.1", "8080");
printf("Listening on %s:%s\n", "127.0.0.1", "8080");
/*
- * Accept connection on the socket
+ * Server command-line interface
*/
- int pid_connections = fork();
- if (pid_connections == 0) {
- // Client address
- struct sockaddr_in sa_client = {
- .sin_family = AF_INET,
- .sin_port = 0,
- .sin_addr.s_addr = 0,
- };
- socklen_t sa_client_size = sizeof(struct sockaddr_in);
-
- // Data for pselect
- fd_set rfds;
- struct timespec tv = {
- .tv_sec = 0,
- .tv_nsec = 100000,
- };
-
- int fd_client;
- int count = 0;
- int pselectStat = 0;
-
- // Effecitvely stops the cycle on SIGTERM
- signal(SIGTERM, handler_refuseConnections);
-
- while (acceptConnections) {
- /* Check if fd_socket has something we can read */
- FD_ZERO(&rfds);
- FD_SET(fd_socket, &rfds);
-
- herrc(pselect(fd_socket + 1, &rfds, NULL, NULL, &tv, NULL), "pselect");
- if (!FD_ISSET(fd_socket, &rfds)) continue;
-
- /* If so, accept the connection and pass execution to the "main" logic */
- fd_client = accept(fd_socket, (struct sockaddr*)&sa_client, &sa_client_size);
- herrc(fd_client, "accept");
- if (fd_client < 0) continue;
-
- char* strAddr = inet_ntoa(sa_client.sin_addr);
- count++;
-
- int fp = fork();
- if (fp == 0) {
- close(fd_socket);
- on_connection(strAddr, fd_client, vhosts, argc - 1);
- close(fd_client);
- freeVhosts(vhosts, argc);
- return 0;
- }
- close(fd_client);
- }
-
- while(wait(NULL) > 0);
- freeVhosts(vhosts, argc);
+ int pid_cli = fork();
+ if (pid_cli == 0) {
close(fd_socket);
-
+ handleCLI(vhosts, argc-1);
+ freeVhosts(vhosts, argc);
+ //while(wait(NULL) > 0);
return 0;
}
/*
- * Server command-line interface
+ * Define variables
*/
- close(fd_socket);
+ // Client address
+ struct sockaddr_in sa_client = {
+ .sin_family = AF_INET,
+ .sin_port = 0,
+ .sin_addr.s_addr = 0,
+ };
+ socklen_t sa_client_size = sizeof(struct sockaddr_in);
- // Get a line
- char line[256];
- fgets(line, 256, stdin);
+ int fd_client;
+ int count = 0;
+ int pselectStat = 0;
- // Get command name and it's arguments
- // Currently no command takes arguments
- char name[MAX_LEN_COMMAND+1];
- int argsAssigned = sscanf(line, COMMAND_FORMAT, name);
+ /*
+ * Handle connection requests
+ */
- while (name[0] != 'q' && name[0] != 'e' && !streq(name, "quit") && !streq(name, "exit")) {
- if (argsAssigned < 1) {
- printf("Bad command syntax!\n");
- }
- else if (streq(name, "vhosts")) {
- for (int i = 1; i < argc; i++) {
- printf("Name: \"%s\" Root dir: \"%s\" Error file: \"%s\"\n",
- vhosts[i-1][vh_user],
- vhosts[i-1][vh_path],
- vhosts[i-1][vh_error]);
- }
- }
- else if (streq(name, "help")) {
- printf("help\tPrints this message\nvhosts\tPrints all registered virtual hosts\n");
- }
- else {
- printf("Unknown command %s!\n", name);
- }
+ // Data for pselect
+ fd_set rfds;
+ struct timespec tv = {
+ /* How long should we block (wait) for fd_socket to have a request */
+ .tv_sec = 0,
+ .tv_nsec = 100000,
+ };
- // Get line and divided it into command name and arguments
- fgets(line, 256, stdin);
- argsAssigned = sscanf(line, COMMAND_FORMAT, name);
- }
+ // Stop accepting connections on SIGTERM
+ signal(SIGTERM, handler_refuseConnections);
- /*
- * Upon termination
- */
+ while (acceptConnections) {
+ /*
+ * Check if fd_socket has something we can read
+ */
- printf("Exiting...\n");
- kill(pid_connections, SIGTERM);
- while(wait(NULL) > 0);
+ FD_ZERO(&rfds);
+ FD_SET(fd_socket, &rfds);
+
+ herrc(pselect(fd_socket + 1, &rfds, NULL, NULL, &tv, NULL), "pselect");
+ if (!FD_ISSET(fd_socket, &rfds)) continue;
+
+ /*
+ * Accept the connection
+ */
+
+ fd_client = accept(fd_socket, (struct sockaddr*)&sa_client, &sa_client_size);
+ herrc(fd_client, "accept");
+ if (fd_client < 0) continue;
- freeVhosts(vhosts, argc);
+ char* strAddr = inet_ntoa(sa_client.sin_addr);
+ count++;
+
+ /*
+ * Logic when connected with client
+ */
+
+ int fp = fork();
+ if (fp == 0) {
+ close(fd_socket);
+ on_connection(strAddr, fd_client, vhosts, argc - 1);
+ close(fd_client);
+ freeVhosts(vhosts, argc);
+ return 0;
+ }
+ close(fd_client);
+ }
+
+ while(wait(NULL) > 0);
+ freeVhosts(vhosts, argc - 1);
+ close(fd_socket);
}