diff options
| author | Soikk | 2025-12-06 20:16:37 +0100 |
|---|---|---|
| committer | Soikk | 2025-12-06 20:19:18 +0100 |
| commit | a55c8ef63bb4941fdee5ddf00ed564e246c8a939 (patch) | |
| tree | eed8f07ee9c2deb5d82d9dac130ef228a0b7b705 /src/worker.c | |
| parent | 534303b80b5304a2b29d456d6b5c7a6ac1daaf1c (diff) | |
| download | soikk-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-x | src/worker.c | 101 |
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() |
