Implemented Hello World
This commit is contained in:
		
							
								
								
									
										7
									
								
								run.sh
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								run.sh
									
									
									
									
									
								
							| @@ -1,7 +1,6 @@ | ||||
| #!/bin/bash | ||||
| echo "-- Building and starting Necronda Server..." | ||||
| make compile && \ | ||||
|  echo -e "-- Successfully finished compiling!\n" && \ | ||||
|  sleep 0.0625 && \ | ||||
|  echo -e "-- Starting Server...\n" && \ | ||||
|  authbind ./bin/necronda-server | ||||
|  echo "-- Successfully finished compiling!" && \ | ||||
|  echo "-- Starting Server..." && \ | ||||
|  ./bin/necronda-server | ||||
|   | ||||
							
								
								
									
										29
									
								
								src/client.c
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								src/client.c
									
									
									
									
									
								
							| @@ -5,6 +5,10 @@ | ||||
|  * Lorenz Stechauner, 2020-12-03 | ||||
|  */ | ||||
|  | ||||
| #include <sys/types.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include "necronda-server.h" | ||||
| #include "utils.h" | ||||
| #include "net/http.h" | ||||
|  | ||||
| @@ -23,3 +27,28 @@ int client_connection_handler() { | ||||
|     // TODO implement client_connection_handler | ||||
|     return 0; | ||||
| } | ||||
|  | ||||
| pid_t client_handler(int socket) { | ||||
|     struct sockaddr_in client_addr; | ||||
|     unsigned int client_addr_len = sizeof(client_addr); | ||||
|  | ||||
|     int client = accept(socket, (struct sockaddr *) &client_addr, &client_addr_len); | ||||
|     if (client == -1) { | ||||
|         fprintf(stderr, ERR_STR "Unable to accept connection: %s" CLR_STR "\n", strerror(errno)); | ||||
|         return -1; | ||||
|     } | ||||
|  | ||||
|     pid_t pid = fork(); | ||||
|     if (pid == 0) { | ||||
|         // child | ||||
|         recv(client, NULL, 0, 0); | ||||
|         char buf[] = "Hello world!\n"; | ||||
|         send(client, buf, strlen(buf), 0); | ||||
|         close(client); | ||||
|         return 0; | ||||
|     } else { | ||||
|         // parent | ||||
|         close(client); | ||||
|         return pid; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -5,14 +5,105 @@ | ||||
|  * Lorenz Stechauner, 2020-12-03 | ||||
|  */ | ||||
|  | ||||
| #include "necronda-server.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <sys/socket.h> | ||||
| #include <signal.h> | ||||
| #include <sys/select.h> | ||||
| #include <string.h> | ||||
| #include <errno.h> | ||||
| #include <arpa/inet.h> | ||||
|  | ||||
| #include "utils.c" | ||||
| #include "net/http.c" | ||||
| #include "client.c" | ||||
|  | ||||
|  | ||||
| int main(int argc, const char* argv[]) { | ||||
| int main(int argc, const char *argv[]) { | ||||
|     const int YES = 1; | ||||
|     fd_set socket_fds, read_socket_fds; | ||||
|     int max_socket_fd = 0; | ||||
|     int ready_sockets_num = 0; | ||||
|  | ||||
|     const struct sockaddr_in addresses[2] = { | ||||
|             {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(8080)}, | ||||
|             {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, .sin_port = htons(4443)} | ||||
|     }; | ||||
|     const struct sockaddr_in6 addresses6[2] = { | ||||
|             {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(8080)}, | ||||
|             {.sin6_family = AF_INET6, .sin6_addr = IN6ADDR_ANY_INIT, .sin6_port = htons(4443)} | ||||
|     }; | ||||
|  | ||||
|     printf("Necronda Web Server\n"); | ||||
|     // TODO implement main | ||||
|  | ||||
|     SOCKETS[0] = socket(AF_INET, SOCK_STREAM, 0); | ||||
|     if (SOCKETS[0] == -1) goto socket_err; | ||||
|     SOCKETS[1] = socket(AF_INET, SOCK_STREAM, 0); | ||||
|     if (SOCKETS[1] == -1) goto socket_err; | ||||
|     SOCKETS[2] = socket(AF_INET6, SOCK_STREAM, 0); | ||||
|     if (SOCKETS[2] == -1) goto socket_err; | ||||
|     SOCKETS[3] = socket(AF_INET6, SOCK_STREAM, 0); | ||||
|     if (SOCKETS[3] == -1) { | ||||
|         socket_err: | ||||
|         fprintf(stderr, ERR_STR "Unable to create socket: %s" CLR_STR "\n", strerror(errno)); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     for (int i = 0; i < NUM_SOCKETS; i++) { | ||||
|         if (setsockopt(SOCKETS[i], SOL_SOCKET, SO_REUSEADDR, &YES, sizeof(YES)) == -1) { | ||||
|             fprintf(stderr, ERR_STR "Unable to set options for socket %i: %s" CLR_STR "\n", i, strerror(errno)); | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (bind(SOCKETS[0], (struct sockaddr *) &addresses[0], sizeof(addresses[0])) == -1) goto bind_err; | ||||
|     if (bind(SOCKETS[1], (struct sockaddr *) &addresses[1], sizeof(addresses[1])) == -1) goto bind_err; | ||||
|     if (bind(SOCKETS[2], (struct sockaddr *) &addresses6[0], sizeof(addresses6[0])) == -1) goto bind_err; | ||||
|     if (bind(SOCKETS[3], (struct sockaddr *) &addresses6[1], sizeof(addresses6[1])) == -1) { | ||||
|         bind_err: | ||||
|         fprintf(stderr, ERR_STR "Unable to bind socket to address: %s" CLR_STR "\n", strerror(errno)); | ||||
|         return 1; | ||||
|     } | ||||
|  | ||||
|     // TODO implement TLS server side handshake | ||||
|  | ||||
|     for (int i = 0; i < NUM_SOCKETS; i++) { | ||||
|         if (listen(SOCKETS[i], LISTEN_BACKLOG) == -1) { | ||||
|             fprintf(stderr, ERR_STR "Unable to listen on socket %i: %s" CLR_STR "\n", i, strerror(errno)); | ||||
|             return 1; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     FD_ZERO(&socket_fds); | ||||
|     for (int i = 0; i < NUM_SOCKETS; i++) { | ||||
|         FD_SET(SOCKETS[i], &socket_fds); | ||||
|         if (SOCKETS[i] > max_socket_fd) { | ||||
|             max_socket_fd = SOCKETS[i]; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     while (1) { | ||||
|         read_socket_fds = socket_fds; | ||||
|         ready_sockets_num = select(max_socket_fd, &read_socket_fds, NULL, NULL, NULL); | ||||
|         if (ready_sockets_num == -1) { | ||||
|             fprintf(stderr, ERR_STR "Unable to select sockets: %s" CLR_STR "\n", strerror(errno)); | ||||
|             return 1; | ||||
|         } | ||||
|  | ||||
|         for (int i = 0; i < NUM_SOCKETS; i++) { | ||||
|             if (FD_ISSET(SOCKETS[i], &read_socket_fds)) { | ||||
|                 pid_t child = client_handler(SOCKETS[i]); | ||||
|                 if (child == 0) { | ||||
|                     return 0; | ||||
|                 } else if (child > 0) { | ||||
|                     for (int j = 0; j < MAX_CHILDREN; j++) { | ||||
|                         if (CHILDREN[j] == 0) { | ||||
|                             CHILDREN[j] = child; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										25
									
								
								src/necronda-server.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/necronda-server.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /** | ||||
|  * Necronda Web Server | ||||
|  * Main executable (header file) | ||||
|  * src/necronda-server.c | ||||
|  * Lorenz Stechauner, 2020-12-03 | ||||
|  */ | ||||
|  | ||||
| #ifndef NECRONDA_SERVER_NECRONDA_SERVER_H | ||||
| #define NECRONDA_SERVER_NECRONDA_SERVER_H | ||||
|  | ||||
| #include <sys/types.h> | ||||
|  | ||||
|  | ||||
| #define NUM_SOCKETS 4 | ||||
| #define MAX_CHILDREN 1024 | ||||
| #define LISTEN_BACKLOG 16 | ||||
|  | ||||
| #define ERR_STR "\x1B[1;31m" | ||||
| #define CLR_STR "\x1B[0m" | ||||
|  | ||||
| int SOCKETS[NUM_SOCKETS]; | ||||
| pid_t CHILDREN[MAX_CHILDREN]; | ||||
|  | ||||
|  | ||||
| #endif //NECRONDA_SERVER_NECRONDA_SERVER_H | ||||
		Reference in New Issue
	
	Block a user