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