diff --git a/Makefile b/Makefile index 52811f2..2866853 100644 --- a/Makefile +++ b/Makefile @@ -1,19 +1,18 @@ CC = gcc -CFLAGS = -std=c99 -Wall -D_POSIX_C_SOURCE=201112L -D_XOPEN_SOURCE=500 -D_GNU_SOURCE +CFLAGS = -std=c99 -Wall -D_POSIX_C_SOURCE=201112L -D_XOPEN_SOURCE=500 -D_GNU_SOURCE -static -g LD = gcc LDFLAGS = -lpthread -lrt BIN_NAME = cfloor -OBJS = obj/networking.o obj/linked.o obj/logging.o obj/signals.o obj/headers.o obj/misc.o obj/status.o obj/files.o obj/mime.o obj/cgi.o obj/util.o +OBJS = obj/networking.o obj/linked.o obj/logging.o obj/signals.o obj/headers.o obj/misc.o obj/status.o obj/files.o obj/mime.o obj/cgi.o obj/util.o obj/ssl.o DEPS = $(OBJS:%.o=%.d) all: $(BIN_NAME) ssl: CFLAGS += -DSSL_SUPPORT -Icrypto -ssl: LDFLAGS += -lcrypto -ssl: OBJS += obj/ssl.o -ssl: $(BIN_NAME) +ssl: LDFLAGS += -lcrypto -lssl +ssl: obj/ssl.o $(BIN_NAME) $(BIN_NAME): obj/main.o $(OBJS) $(LD) $(LDFLAGS) -o $@ $^ diff --git a/src/main.c b/src/main.c index 635ec29..c0dc185 100644 --- a/src/main.c +++ b/src/main.c @@ -9,11 +9,35 @@ #include "files.h" #include "cgi.h" #include "util.h" +#include "signals.h" #ifdef SSL_SUPPORT #include "ssl.h" #endif +struct headers headers; +char* documentRoot = NULL; + +void shutdownHandler() { + info("main: shutting down"); + + headers_free(&headers); + + if (documentRoot != NULL) + free(documentRoot); + + #ifdef SSL_SUPPORT + ssl_destroy(); + #endif + + exit(0); +} + +void sigHandler(int signo) { + info("main: signal %d", signo); + shutdownHandler(); +} + struct handlerSettings { struct fileSettings fileSettings; struct cgiSettings cgiSettings; @@ -48,7 +72,10 @@ int main(int argc, char** argv) { setLogging(stderr, DEBUG, true); setCriticalHandler(NULL); - char* documentRoot = realpath("./home/", NULL); + signal_setup(SIGINT, &sigHandler); + signal_setup(SIGTERM, &sigHandler); + + documentRoot = realpath("./home/", NULL); struct handlerSettings handlerSettings = { .fileSettings = { @@ -70,12 +97,27 @@ int main(int argc, char** argv) { union userData settingsData; settingsData.ptr = &handlerSettings; - struct headers headers = headers_create(); + headers = headers_create(); headers_mod(&headers, "Server", "CFloor 0.1"); + #ifdef SSL_SUPPORT + ssl_init(); + + struct ssl_settings ssl_settings = (struct ssl_settings) { + .privateKey = "certs/hiro.key", + .certificate = "certs/hiro.crt" + }; + + if (ssl_initSettings(&(ssl_settings)) < 0) { + error("main: error setting up ssl settings"); + return 1; + } + #endif + + struct networkingConfig config = { .maxConnections = 1024, - .connectionTimeout = 30000, + .connectionTimeout = 2000, .binds = { .number = 1, .binds = (struct bind[]) { @@ -85,7 +127,7 @@ int main(int argc, char** argv) { .settings = settingsData, #ifdef SSL_SUPPORT - .ssl_settings = NULL + .ssl_settings = &ssl_settings #endif } } @@ -100,6 +142,5 @@ int main(int argc, char** argv) { sleep(0xffff); } - headers_free(&headers); - free(documentRoot); + shutdownHandler(); } diff --git a/src/networking.c b/src/networking.c index 99a90a7..c5a67b6 100644 --- a/src/networking.c +++ b/src/networking.c @@ -73,7 +73,7 @@ void cleanup() { if (connection->state != OPENED) { unlink = true; } else if (diffms > networkingConfig.connectionTimeout) { - unlink = true; + connection->state = ABORTED; } if (unlink) { @@ -415,6 +415,7 @@ void dataHandler(int signo) { struct connection* connection = link->data; if (connection->state != OPENED) continue; + connection->inUse++; int tmp; char c; char buffer[BUFFER_LENGTH]; @@ -424,6 +425,7 @@ void dataHandler(int signo) { if (connection->currentHeaderLength > 0) last = connection->currentHeader[connection->currentHeaderLength - 1]; while((tmp = read(connection->readfd, &c, 1)) > 0) { + printf("%c", c); if (last == '\r' && c == '\n') { if (dumpHeaderBuffer(&(buffer[0]), length, connection) < 0) { dropConnection = true; @@ -526,6 +528,8 @@ void dataHandler(int signo) { setSIGIO(connection->readfd, false); connection->state = ABORTED; } + + connection->inUse--; } } void* dataThread(void* ignore) { @@ -682,11 +686,17 @@ void* listenThread(void* _bind) { snprintf(&(peer.portStr[0]), 5 + 1, "%d", peer.port); + info("networking: new connection from %s:%s", peer.addr, peer.portStr); + + connection->readfd = tmp; + connection->writefd = tmp; + #ifdef SSL_SUPPORT if (bindObj->ssl_settings != NULL) { struct ssl_connection* sslConnection = ssl_initConnection(bindObj->ssl_settings, tmp); if (sslConnection == NULL) { free(connection); + close(tmp); error("networking: failed to open ssl connection"); continue; } @@ -696,8 +706,6 @@ void* listenThread(void* _bind) { connection->writefd = sslConnection->writefd; } else { connection->sslConnection = NULL; - connection->readfd = tmp; - connection->writefd = tmp; } #endif diff --git a/src/ssl.c b/src/ssl.c index 6f362dd..00d583e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1,16 +1,18 @@ +#ifdef SSL_SUPPORT + #include #include #include #include #include -#include #include #include #include #include "ssl.h" #include "logging.h" +#include "misc.h" void ssl_init() { SSL_load_error_strings(); @@ -26,7 +28,7 @@ int ssl_initSettings(struct ssl_settings* settings) { SSL_CTX* ctx = SSL_CTX_new( SSLv23_server_method()); SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE); - if (!SSL_CTX_use_certificate_file(sslctx, settings->certificate, SSL_FILETYPE_PEM)) { + if (!SSL_CTX_use_certificate_file(ctx, settings->certificate, SSL_FILETYPE_PEM)) { error("ssl: failed to set cert file for ctx: %s", ERR_error_string(ERR_get_error(), NULL)); return -1; } @@ -36,7 +38,7 @@ int ssl_initSettings(struct ssl_settings* settings) { return -1; } - _private.ctx = ctx; + settings->_private.ctx = ctx; return 0; } @@ -49,7 +51,9 @@ void* copyFromSslToFd(void* data) { write(connection->_readfd, &b, 1); } - close(connection->_writefd); + close(connection->_readfd); + + return NULL; } void* copyFromFdToSsl(void* data) { @@ -59,6 +63,8 @@ void* copyFromFdToSsl(void* data) { while(read(connection->_writefd, &b, 1) == 1) { SSL_write(connection->instance, &b, 1); } + + return NULL; } struct ssl_connection* ssl_initConnection(struct ssl_settings* settings, int socket) { @@ -76,6 +82,7 @@ struct ssl_connection* ssl_initConnection(struct ssl_settings* settings, int soc connection->_threads[1] = PTHREAD_NULL; connection->instance = SSL_new(settings->_private.ctx); + info("ssl: instance created"); if (connection->instance == NULL) { free(connection); @@ -121,11 +128,13 @@ struct ssl_connection* ssl_initConnection(struct ssl_settings* settings, int soc return NULL; } + info("ssl: copy threads started"); + return connection; } -int ssl_closeConnection(struct ssl_connection* connection) { +void ssl_closeConnection(struct ssl_connection* connection) { close(connection->writefd); close(connection->readfd); close(connection->_writefd); @@ -133,15 +142,17 @@ int ssl_closeConnection(struct ssl_connection* connection) { if (connection->_threads[0] != PTHREAD_NULL) { pthread_cancel(connection->_threads[0]); - pthread_join(connection->_threads[0]); + pthread_join(connection->_threads[0], NULL); } if (connection->_threads[1] != PTHREAD_NULL) { pthread_cancel(connection->_threads[1]); - pthread_join(connection->_threads[1]); + pthread_join(connection->_threads[1], NULL); } SSL_shutdown(connection->instance); SSL_free(connection->instance); free(connection); } + +#endif diff --git a/src/ssl.h b/src/ssl.h index 5932698..31a3075 100644 --- a/src/ssl.h +++ b/src/ssl.h @@ -27,6 +27,6 @@ void ssl_destroy(); int ssl_initSettings(struct ssl_settings* settings); struct ssl_connection* ssl_initConnection(struct ssl_settings* settings, int socket); -int ssl_closeConnection(struct ssl_connection* connection); +void ssl_closeConnection(struct ssl_connection* connection); #endif