summaryrefslogtreecommitdiff
path: root/src/worker.c
diff options
context:
space:
mode:
authorSoikk2025-12-06 20:16:37 +0100
committerSoikk2025-12-06 20:19:18 +0100
commita55c8ef63bb4941fdee5ddf00ed564e246c8a939 (patch)
treeeed8f07ee9c2deb5d82d9dac130ef228a0b7b705 /src/worker.c
parent534303b80b5304a2b29d456d6b5c7a6ac1daaf1c (diff)
downloadsoikk-server-a55c8ef63bb4941fdee5ddf00ed564e246c8a939.tar.xz
soikk-server-a55c8ef63bb4941fdee5ddf00ed564e246c8a939.tar.zst
Reworked worker architecture
- replaced the central socket-multiple accepts architecture thanks to SO_REUSEPORT - removed master/worker distinctions for server and config - fixed bug with rewrites not being read properly by multiple workers because of null characters
Diffstat (limited to 'src/worker.c')
-rwxr-xr-xsrc/worker.c101
1 files changed, 39 insertions, 62 deletions
diff --git a/src/worker.c b/src/worker.c
index b919b64..ce185bd 100755
--- a/src/worker.c
+++ b/src/worker.c
@@ -6,14 +6,13 @@
#include "config/config.h"
-config_w config;
struct {
str path;
- str socket_path;
str config_file;
str self;
} dir;
-http_worker *worker;
+config conf;
+http_server *server;
// remove these or something
int secure = 0;
@@ -21,13 +20,13 @@ int secure = 0;
void deinit(void);
-void quit(int sig, siginfo_t *info, void *ucontext){
+static void quit(int sig, siginfo_t *info, void *ucontext){
log_info("Terminating due to SIG%s (%s)", sigabbrev_np(sig), sigdescr_np(sig));
deinit();
exit(0);
}
-int signal_wait(int sig){
+static int signal_wait(int sig){
sigset_t old, new;
sigemptyset(&new);
sigaddset(&new, sig);
@@ -45,27 +44,23 @@ int signal_wait(int sig){
return 0;
}
-void reinit(int sig, siginfo_t *info, void *ucontext){
+static void reinit(int sig, siginfo_t *info, void *ucontext){
if(sig == SIGUSR1){
log_info("Reinitializing worker");
- free_worker_config(&config);
- destroy_http_worker(&worker);
+ free_config(&conf);
+ destroy_http_server(&server);
if(signal_wait(SIGCONT) != 0){
log_error("You should probably look at signal_wait to see wtf is going on");
}
- config = worker_config(dir.config_file.ptr);
- if(config.file.ptr == NULL){
+ conf = read_config(dir.config_file.ptr);
+ if(conf.file.ptr == NULL){
log_error("Unable to read config from '%.*s'", dir.config_file.len, dir.config_file.ptr);
quit(SIGTERM, NULL, NULL);
}
- int sfd = open(dir.socket_path.ptr, O_RDONLY);
- int ssocket;
- read(sfd, &ssocket, sizeof(int));
- close(sfd);
- worker = setup_http_worker(ssocket, secure, config.cert, config.key);
- if(worker == NULL){
+ server = setup_http_server(conf.port, conf.backlog);
+ if(server == NULL){
log_error("Error setting up worker server");
quit(SIGTERM, NULL, NULL);
}
@@ -73,17 +68,12 @@ void reinit(int sig, siginfo_t *info, void *ucontext){
}
// possibly change name
-int read_server_dir(str name){
+static int read_server_dir(str name){
dir.path = dup_strs(sstr("/var/run/"), name, sstr("/"));
if(!dir_exists(dir.path.ptr)){
log_error("No server directory in '%.*s'", dir.path.len, dir.path.ptr);
return 1;
}
- dir.socket_path = dup_strs(dir.path, sstr("socket"));
- if(!file_exists(dir.socket_path.ptr)){
- log_error("No socket file in '%.*s'", dir.socket_path.len, dir.socket_path.ptr);
- return 1;
- }
dir.config_file = dup_strs(dir.path, sstr("configfile"));
if(!file_exists(dir.config_file.ptr)){
log_error("No config file in '%.*s'", dir.config_file.len, dir.config_file.ptr);
@@ -93,10 +83,6 @@ int read_server_dir(str name){
str pid = utostr(getpid(), 10);
dir.self = dup_strs(dir.path, sstr("workers/"), pid);
free_str(&pid);
- if(file_exists(dir.self.ptr)){
- log_error("Error creating PID record for self in '%.*s': it already exists", dir.self.len, dir.self.ptr);
- return 1;
- }
if(creat(dir.self.ptr, 0777) == -1){
log_error("Error creating PID record for self in '%.*s': %s", dir.self.len, dir.self.ptr, strerror(errno));
return 1;
@@ -104,25 +90,29 @@ int read_server_dir(str name){
return 0;
}
+// possibly change name
+static void remove_server_dir(void){
+ if(remove(dir.self.ptr) != 0){
+ log_error("Error removing PID record for self in '%.*s': %s", dir.self.len, dir.self.ptr, strerror(errno));
+ }
+ free_str(&dir.self);
+ free_str(&dir.config_file);
+ free_str(&dir.path);
+}
+
int init(str name){
if(read_server_dir(name) != 0){
log_error("Error reading server directory");
return 1;
}
- config = worker_config(dir.config_file.ptr);
- if(config.file.ptr == NULL){
+ conf = read_config(dir.config_file.ptr);
+ if(conf.file.ptr == NULL){
log_error("Unable to read config from '%.*s'", dir.config_file.len, dir.config_file.ptr);
return 1;
}
//print_worker_config(config);
- // TODO: remove "successful" messages or add them all
- log_info("Succesfully read worker config from '%.*s'", dir.config_file.len, dir.config_file.ptr);
- int sfd = open(dir.socket_path.ptr, O_RDONLY);
- int ssocket;
- read(sfd, &ssocket, sizeof(int));
- close(sfd);
- worker = setup_http_worker(ssocket, secure, config.cert, config.key);
- if(worker == NULL){
+ server = setup_http_server(conf.port, conf.backlog);
+ if(server == NULL){
log_error("Error setting up worker server");
return 1;
}
@@ -147,30 +137,17 @@ int init(str name){
return 0;
}
-// possibly change name
-void remove_server_dir(void){
- if(remove(dir.self.ptr) != 0){
- log_error("Error removing PID record for self in '%.*s': %s", dir.self.len, dir.self.ptr, strerror(errno));
- }
- free_str(&dir.self);
- free_str(&dir.path);
-}
-
void deinit(void){
- free_worker_config(&config);
+ destroy_http_server(&server);
+ free_config(&conf);
remove_server_dir();
- destroy_http_worker(&worker);
-}
-
-void print_usage(void){
- printf("worker [server name]\n");
}
int main(int argc, char **argv){
if(argc < 2){
- print_usage();
+ printf("worker [server name]\n");
return 1;
}
@@ -187,24 +164,24 @@ int main(int argc, char **argv){
while(1){
char cip[INET_ADDRSTRLEN] = {0};
- return_value = accept_connection(worker, cip);
+ return_value = accept_connection(server, cip);
switch(return_value){
case -1: // couldnt accept, do something ig
continue;
case SSL_ERROR_SSL:
- reset_https(worker);
+ reset_https(server);
log_info("continuing\n");
continue;
}
- log_info("socket %d accepted with ip %s", worker->csocket, cip);
- return_value = receive_request(worker, &request);
+ log_info("socket %d accepted with ip %s", server->csocket, cip);
+ return_value = receive_request(server, &request);
log_debug("received %d from receive_request", return_value);
switch(return_value){
case -1: // couldnt accept, do something ig
goto finish_request;
break;
case SSL_ERROR_SSL:
- reset_https(worker);
+ reset_https(server);
log_info("continuing\n");
continue;
}
@@ -221,13 +198,13 @@ int main(int argc, char **argv){
switch(method){
case GET:
str resource = generate_resource(surl, hm.url);
- send_file(worker, resource);
+ send_file(server, resource);
//if(resource.temp == true) remove(resource.name.ptr);
free_str(&resource);
break;
case POST:
//handlePOST(request);
- send(worker->csocket, "HTTP/1.1 201 Created\r\n\r\n", len("HTTP/1.1 201 Created\r\n\r\n"), 0);
+ send(server->csocket, "HTTP/1.1 201 Created\r\n\r\n", len("HTTP/1.1 201 Created\r\n\r\n"), 0);
break;
case PUT:
break;
@@ -243,10 +220,10 @@ finish_request:
log_debug("query freed");
request.len = 0;
- if(worker->secure){
- SSL_clear(worker->ssl);
+ if(server->secure){
+ SSL_clear(server->ssl);
}
- close(worker->csocket);
+ close(server->csocket);
//SSL_shutdown(config.ssl); // look into SSL_clear()