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