Skip to content

Prefork #4

Merged
merged 4 commits into from
May 20, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 23 additions & 46 deletions mxshadowsrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@
#include <string.h>
#include <getopt.h>
#include <pthread.h>
#include <semaphore.h>
#ifdef DEBUG_MAX_CONNECTS
#include <sys/wait.h>
#endif

#include "common.h"

Expand Down Expand Up @@ -66,14 +62,15 @@ static void unmap_shadow(char *shadow_buf, struct stat *statbuf) {
if (sts == -1) { perror("munmap"); exit(1); }
}

#define MAX_THREADS 8
#define THREADS 8
#define TIMEOUT 30000 // client timeout in msec

static pthread_mutex_t shadow_mutex = PTHREAD_MUTEX_INITIALIZER ;
static char *shadow_buf = NULL; // protected by shadow_mutex
static struct stat statbuf; // protected by shadow_mutex
static SSL_CTX *ssl_ctx;
static sem_t free_worker;
static int listen_socket;
static char *filename;
#ifdef DEBUG_MAX_CONNECTS
static int debug_remaining_connects = DEBUG_MAX_CONNECTS;
#endif
Expand Down Expand Up @@ -193,12 +190,17 @@ static void process_client(int socket) {
}

static void *client_thread(void *arg) {
int socket = *((int *)arg);
process_client(socket);
close(socket);
free(arg);
int status = sem_post(&free_worker);
if (status != 0) { errno = status; perror("sem_post"); exit(1); }

while (1) {
#ifdef DEBUG_MAX_CONNECTS
if ( __sync_fetch_and_sub(&debug_remaining_connects, 1) <= 0)
return NULL;
#endif
int _cleanup_(free_fd) socket = accept4(listen_socket, NULL, NULL, SOCK_NONBLOCK);
if (socket == -1 ) { perror("accept"); exit(1); }
validate_shadow(&shadow_buf, filename, &statbuf);
process_client(socket);
}
return NULL;
}

Expand Down Expand Up @@ -239,7 +241,7 @@ int main(int argc, char **argv) {
die_usage(argv[0]);
if (optind+1 != argc)
die_usage(argv[0]);
char *filename = argv[optind++];
filename = argv[optind++];

SSL_CTX *_ssl_ctx _cleanup_(free_ssl_ctx) = SSL_CTX_new(TLS_server_method());
if (_ssl_ctx == NULL) { psslerror("SSL_CTX_new"); return 1; }
Expand All @@ -248,7 +250,7 @@ int main(int argc, char **argv) {
if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) <= 0 ) { psslerror("SSL_CTX_use_PrivateKey_file"); return 1; }
if (SSL_CTX_use_certificate_file(ssl_ctx, cert_file, SSL_FILETYPE_PEM) <= 0) { psslerror("SSL_CTX_use_certificate_file"); return 1; }

int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
listen_socket = socket(AF_INET, SOCK_STREAM, 0);
if (listen_socket == -1) { perror("socket"); return 1; }

static int true = 1;
Expand All @@ -265,38 +267,13 @@ int main(int argc, char **argv) {
status = listen(listen_socket, 40);
if (status == -1) { perror("listen"); exit(1); }

status = sem_init(&free_worker, 0, MAX_THREADS);
if (status) { errno = status; perror("sem_init"); exit(1); }

while (1) {
#ifdef DEBUG_MAX_CONNECTS
if (debug_remaining_connects-- == 0)
break;
#endif
int _cleanup_(free_fd) socket = accept4(listen_socket, NULL, NULL, SOCK_NONBLOCK);
if (socket == -1 ) { perror("accept"); exit(1); }
status = sem_wait(&free_worker);
if (status == -1) { perror("sem_wait"); exit(1); }
validate_shadow(&shadow_buf, filename, &statbuf);
pthread_t thread;
int *arg = malloc(sizeof *arg);
if (arg == NULL) { perror("malloc"); exit(1); }
*arg = socket;
status = pthread_create(&thread, NULL, client_thread, arg);
pthread_t thread[THREADS];
for (int i=0; i<THREADS; i++) {
int status = pthread_create(&thread[i], NULL, client_thread, NULL);
if (status != 0) { errno = status; perror("pthread_create"); exit(1); }
socket = -1;
status = pthread_detach(thread);
if (status != 0) { errno = status; perror("pthread_detach"); exit(1); }

}
#ifdef DEBUG_MAX_CONNECTS
for (int i=0; i<MAX_THREADS; i++) {
status = sem_wait(&free_worker);
if (status == -1) { perror("sem_wait"); exit(1); }
}
/* Valgrinds checks on exit() race with pthread_exit() and Valgrind might report
* a threads stack as lost memory or a Helgrind detected data race. Give threads
* a little time to exit after they posted the semaphore */
sleep(1);
#endif
for (int i=0; i<THREADS; i++) {
int status = pthread_join(thread[i], NULL);
if (status != 0) { errno = status; perror("pthread_join"); exit(1); }
}
}