3 Commits

12 changed files with 74 additions and 91 deletions

View File

@@ -40,23 +40,23 @@ bin/%.o: src/%.c
bin/lib/%.o: src/lib/%.c
$(CC) -c -o $@ $(CFLAGS) $<
bin/sesimos: bin/server.o bin/client.o bin/logger.o \
bin/lib/cache.o bin/lib/compress.o bin/lib/config.o bin/lib/fastcgi.o bin/lib/geoip.o \
bin/sesimos: bin/server.o bin/client.o bin/logger.o bin/cache_handler.o \
bin/lib/compress.o bin/lib/config.o bin/lib/fastcgi.o bin/lib/geoip.o \
bin/lib/http.o bin/lib/http_static.o bin/lib/proxy.o bin/lib/sock.o bin/lib/uri.o \
bin/lib/utils.o bin/lib/websocket.o
$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
bin/server.o: src/server.h src/defs.h src/client.h src/lib/cache.h src/lib/config.h src/lib/sock.h \
bin/server.o: src/server.h src/defs.h src/client.h src/cache_handler.h src/lib/config.h src/lib/sock.h \
src/lib/proxy.h src/lib/geoip.h src/lib/utils.h src/logger.h
bin/client.o: src/client.h src/defs.h src/server.h src/lib/utils.h src/lib/config.h src/lib/sock.h \
src/lib/http.h src/lib/proxy.h src/lib/fastcgi.h src/lib/cache.h src/lib/geoip.h src/lib/compress.h \
src/lib/http.h src/lib/proxy.h src/lib/fastcgi.h src/cache_handler.h src/lib/geoip.h src/lib/compress.h \
src/lib/websocket.h src/logger.h
bin/logger.o: src/logger.h
bin/lib/cache.o: src/lib/cache.h src/lib/utils.h src/lib/uri.h src/lib/compress.h src/logger.h
bin/cache_handler.o: src/cache_handler.h src/lib/utils.h src/lib/uri.h src/lib/compress.h src/logger.h
bin/lib/compress.o: src/lib/compress.h

View File

@@ -1,23 +1,22 @@
/**
* sesimos - secure, simple, modern web server
* @brief File cache implementation
* @file src/lib/cache.c
* @file src/cache_handler.c
* @author Lorenz Stechauner
* @date 2020-12-19
*/
#include "../server.h"
#include "../logger.h"
#include "cache.h"
#include "utils.h"
#include "compress.h"
#include "config.h"
#include "server.h"
#include "logger.h"
#include "cache_handler.h"
#include "lib/utils.h"
#include "lib/compress.h"
#include "lib/config.h"
#include <stdio.h>
#include <magic.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <openssl/evp.h>
#include <sys/mman.h>
#include <fcntl.h>
@@ -26,8 +25,7 @@
#define CACHE_BUF_SIZE 16
magic_t magic;
static magic_t magic;
static pthread_t thread;
static sem_t sem_free, sem_used, sem_lock;
@@ -39,8 +37,6 @@ typedef struct {
static buf_t buffer;
static int magic_init(void) {
if ((magic = magic_open(MAGIC_MIME)) == NULL) {
critical("Unable to open magic cookie");
@@ -323,7 +319,7 @@ static void cache_mark_entry_dirty(cache_entry_t *entry) {
sem_post(&sem_used);
}
static int cache_update_entry(cache_entry_t *entry, const char *filename, const char *webroot) {
static void cache_update_entry(cache_entry_t *entry, const char *filename, const char *webroot) {
struct stat statbuf;
stat(filename, &statbuf);
memcpy(&entry->meta.stat, &statbuf, sizeof(statbuf));
@@ -348,8 +344,6 @@ static int cache_update_entry(cache_entry_t *entry, const char *filename, const
strcpy(entry->meta.charset, magic_file(magic, filename));
cache_mark_entry_dirty(entry);
return 0;
}
void cache_mark_dirty(cache_t *cache, const char *filename) {
@@ -357,18 +351,15 @@ void cache_mark_dirty(cache_t *cache, const char *filename) {
if (entry) cache_mark_entry_dirty(entry);
}
int cache_init_uri(cache_t *cache, http_uri *uri) {
if (uri->filename == NULL)
return 0;
void cache_init_uri(cache_t *cache, http_uri *uri) {
if (!uri->filename)
return;
cache_entry_t *entry = cache_get_entry(cache, uri->filename);
if (entry == NULL) {
if (!entry) {
// no entry found -> create new entry
entry = cache_get_new_entry(cache);
if (entry) {
if (cache_update_entry(entry, uri->filename, uri->webroot) != 0) {
return -1;
}
if ((entry = cache_get_new_entry(cache))) {
cache_update_entry(entry, uri->filename, uri->webroot);
uri->meta = &entry->meta;
} else {
warning("No empty cache entry slot found");
@@ -376,18 +367,14 @@ int cache_init_uri(cache_t *cache, http_uri *uri) {
} else {
uri->meta = &entry->meta;
if (entry->flags & CACHE_DIRTY)
return 0;
return;
// check, if file has changed
struct stat statbuf;
stat(uri->filename, &statbuf);
if (memcmp(&uri->meta->stat.st_mtime, &statbuf.st_mtime, sizeof(statbuf.st_mtime)) != 0) {
// modify time has changed
if (cache_update_entry(entry, uri->filename, uri->webroot) != 0) {
return -1;
}
cache_update_entry(entry, uri->filename, uri->webroot);
}
}
return 0;
}

View File

@@ -1,15 +1,15 @@
/**
* sesimos - secure, simple, modern web server
* @brief File cache implementation (header file)
* @file src/lib/cache.h
* @file src/cache_handler.h
* @author Lorenz Stechauner
* @date 2020-12-19
*/
#ifndef SESIMOS_CACHE_H
#define SESIMOS_CACHE_H
#ifndef SESIMOS_CACHE_HANDLER_H
#define SESIMOS_CACHE_HANDLER_H
#include "uri.h"
#include "lib/uri.h"
#define CACHE_ENTRIES 1024
@@ -39,6 +39,6 @@ int cache_join(void);
void cache_mark_dirty(cache_t *cache, const char *filename);
int cache_init_uri(cache_t *cache, http_uri *uri);
void cache_init_uri(cache_t *cache, http_uri *uri);
#endif //SESIMOS_CACHE_H
#endif //SESIMOS_CACHE_HANDLER_H

View File

@@ -17,7 +17,7 @@
#include "lib/http.h"
#include "lib/proxy.h"
#include "lib/fastcgi.h"
#include "lib/cache.h"
#include "cache_handler.h"
#include "lib/geoip.h"
#include "lib/compress.h"
#include "lib/websocket.h"
@@ -252,11 +252,8 @@ int client_request_handler(client_ctx_t *cctx, sock *client, unsigned long clien
goto respond;
}
if ((ret = cache_init_uri(conf->cache, &uri)) != 0) {
res.status = http_get_status(500);
sprintf(err_msg, "Unable to communicate with internal file cache.");
goto respond;
}
cache_init_uri(conf->cache, &uri);
const char *last_modified = http_format_date(uri.meta->stat.st_mtime, buf0, sizeof(buf0));
http_add_header_field(&res.hdr, "Last-Modified", last_modified);
sprintf(buf1, "%s; charset=%s", uri.meta->type, uri.meta->charset);
@@ -719,15 +716,16 @@ int client_request_handler(client_ctx_t *cctx, sock *client, unsigned long clien
return 0;
}
int client_connection_handler(client_ctx_t *ctx, sock *client, unsigned long client_num, const char *restrict log_conn_prefix, const char *restrict log_client_prefix) {
int client_connection_handler(client_ctx_t *ctx, unsigned long client_num, const char *restrict log_conn_prefix, const char *restrict log_client_prefix) {
struct timespec begin, end;
int ret;
char buf[1024];
sock *client = &ctx->socket;
clock_gettime(CLOCK_MONOTONIC, &begin);
if (dns_server[0] != 0) {
sprintf(buf, "dig @%s +short +time=1 -x %s", dns_server, ctx->addr);
if (config.dns_server[0] != 0) {
sprintf(buf, "dig @%s +short +time=1 -x %s", config.dns_server, ctx->addr);
FILE *dig = popen(buf, "r");
if (dig == NULL) {
error("Unable to start dig: %s", strerror(errno));
@@ -751,7 +749,6 @@ int client_connection_handler(client_ctx_t *ctx, sock *client, unsigned long cli
}
ctx->cc[0] = 0;
ctx->geoip[0] = 0;
geoip_lookup_country(&client->addr.sock, ctx->cc);
info("Connection accepted from %s %s%s%s[%s]", ctx->addr, ctx->host[0] != 0 ? "(" : "",
@@ -805,11 +802,9 @@ int client_connection_handler(client_ctx_t *ctx, sock *client, unsigned long cli
return 0;
}
void *client_handler(sock *client) {
void *client_handler(client_ctx_t *ctx) {
struct sockaddr_in6 *server_addr;
struct sockaddr_storage server_addr_storage;
client_ctx_t ctx;
char log_client_prefix[256], log_conn_prefix[512];
logger_set_name("client");
@@ -817,33 +812,33 @@ void *client_handler(sock *client) {
//signal(SIGINT, client_terminate);
//signal(SIGTERM, client_terminate);
inet_ntop(client->addr.ipv6.sin6_family, &client->addr.ipv6.sin6_addr, ctx._c_addr, sizeof(ctx._c_addr));
if (strncmp(ctx._c_addr, "::ffff:", 7) == 0) {
ctx.addr = ctx._c_addr + 7;
inet_ntop(ctx->socket.addr.ipv6.sin6_family, &ctx->socket.addr.ipv6.sin6_addr, ctx->_c_addr, sizeof(ctx->_c_addr));
if (strncmp(ctx->_c_addr, "::ffff:", 7) == 0) {
ctx->addr = ctx->_c_addr + 7;
} else {
ctx.addr = ctx._c_addr;
ctx->addr = ctx->_c_addr;
}
socklen_t len = sizeof(server_addr_storage);
getsockname(client->socket, (struct sockaddr *) &server_addr_storage, &len);
getsockname(ctx->socket.socket, (struct sockaddr *) &server_addr_storage, &len);
server_addr = (struct sockaddr_in6 *) &server_addr_storage;
inet_ntop(server_addr->sin6_family, (void *) &server_addr->sin6_addr, ctx._s_addr, sizeof(ctx._s_addr));
if (strncmp(ctx._s_addr, "::ffff:", 7) == 0) {
ctx.s_addr = ctx._s_addr + 7;
inet_ntop(server_addr->sin6_family, (void *) &server_addr->sin6_addr, ctx->_s_addr, sizeof(ctx->_s_addr));
if (strncmp(ctx->_s_addr, "::ffff:", 7) == 0) {
ctx->s_addr = ctx->_s_addr + 7;
} else {
ctx.s_addr = ctx._s_addr;
ctx->s_addr = ctx->_s_addr;
}
sprintf(log_client_prefix, "[%s%4i%s]%s[%*s][%5i]%s", (int) client->enc ? HTTPS_STR : HTTP_STR,
ntohs(server_addr->sin6_port), CLR_STR, color_table[0], INET6_ADDRSTRLEN, ctx.addr,
ntohs(client->addr.ipv6.sin6_port), CLR_STR);
sprintf(log_client_prefix, "[%s%4i%s]%s[%*s][%5i]%s", (int) ctx->socket.enc ? HTTPS_STR : HTTP_STR,
ntohs(server_addr->sin6_port), CLR_STR, color_table[0], INET6_ADDRSTRLEN, ctx->addr,
ntohs(ctx->socket.addr.ipv6.sin6_port), CLR_STR);
sprintf(log_conn_prefix, "[%*s]%s", INET6_ADDRSTRLEN, ctx.s_addr, log_client_prefix);
sprintf(log_conn_prefix, "[%*s]%s", INET6_ADDRSTRLEN, ctx->s_addr, log_client_prefix);
logger_set_prefix(log_conn_prefix);
info("Started thread");
client_connection_handler(&ctx, client, 0, log_conn_prefix, log_client_prefix);
client_connection_handler(ctx, 0, log_conn_prefix, log_client_prefix);
return NULL;
}

View File

@@ -11,24 +11,23 @@
#include "lib/config.h"
#include "lib/sock.h"
#include "lib/geoip.h"
#include <arpa/inet.h>
typedef struct {
sock socket;
char *addr;
char *s_addr;
unsigned char s_keep_alive:1;
unsigned char c_keep_alive:1;
char cc[3];
char host[256];
char geoip[GEOIP_MAX_JSON_SIZE + 1];
char _c_addr[INET6_ADDRSTRLEN + 1];
char _s_addr[INET6_ADDRSTRLEN + 1];
} client_ctx_t;
host_config_t *get_host_config(const char *host);
void *client_handler(sock *client);
void *client_handler(client_ctx_t *client);
#endif //SESIMOS_CLIENT_H

View File

@@ -14,7 +14,6 @@
#include <stdlib.h>
config_t config;
char geoip_dir[256], dns_server[256];
int config_load(const char *filename) {
FILE *file = fopen(filename, "r");
@@ -77,10 +76,10 @@ int config_load(const char *filename) {
} else if (section == 0) {
if (len > 10 && strncmp(ptr, "geoip_dir", 9) == 0 && (ptr[9] == ' ' || ptr[9] == '\t')) {
source = ptr + 9;
target = geoip_dir;
target = config.geoip_dir;
} else if (len > 11 && strncmp(ptr, "dns_server", 10) == 0 && (ptr[10] == ' ' || ptr[10] == '\t')) {
source = ptr + 10;
target = dns_server;
target = config.dns_server;
} else {
goto err;
}

View File

@@ -10,7 +10,7 @@
#define SESIMOS_CONFIG_H
#include "uri.h"
#include "cache.h"
#include "../cache_handler.h"
#define CONFIG_MAX_HOST_CONFIG 64
#define CONFIG_MAX_CERT_CONFIG 64
@@ -52,10 +52,11 @@ typedef struct {
typedef struct {
host_config_t hosts[CONFIG_MAX_HOST_CONFIG];
cert_config_t certs[CONFIG_MAX_CERT_CONFIG];
char geoip_dir[256];
char dns_server[256];
} config_t;
extern config_t config;
extern char geoip_dir[256], dns_server[256];
int config_load(const char *filename);

View File

@@ -156,9 +156,9 @@ int fastcgi_init(fastcgi_conn *conn, int mode, unsigned int client_num, unsigned
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_LENGTH", content_length != NULL ? content_length : "");
const char *content_type = http_get_header_field(&req->hdr, "Content-Type");
param_ptr = fastcgi_add_param(param_ptr, "CONTENT_TYPE", content_type != NULL ? content_type : "");
if (conn->ctx->geoip[0] != 0) {
param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", conn->ctx->geoip);
}
//if (conn->ctx->geoip[0] != 0) {
// param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", conn->ctx->geoip);
//}
for (int i = 0; i < req->hdr.field_num; i++) {
const http_field *f = &req->hdr.fields[i];

View File

@@ -15,7 +15,7 @@
#define PROXY_COMPRESS 6
#ifndef SERVER_NAME
# define SERVER_NAME "revproxy"
# define SERVER_NAME "reverse proxy"
#endif
#include "http.h"

View File

@@ -20,9 +20,11 @@
#define LOG_MAX_MSG_SIZE 2048
#define LOG_BUF_SIZE 16
#define LOG_NAME_LEN 8
#define LOG_NAME_LEN 12
#define LOG_PREFIX_LEN 256
#define LOG_PREFIX "[%-8s][%-6s]"
typedef struct {
log_lvl_t lvl;
char name[LOG_NAME_LEN];
@@ -58,7 +60,7 @@ static const char *level_keywords[] = {
static void err(const char *restrict msg) {
char err_buf[64];
strerror_r(errno, err_buf, sizeof(err_buf));
fprintf(stderr, ERR_STR "[logger][%6s] %s: %s" CLR_STR "\n", level_keywords[LOG_CRITICAL], msg, err_buf);
fprintf(stderr, ERR_STR LOG_PREFIX " %s: %s" CLR_STR "\n", "logger", level_keywords[LOG_CRITICAL], msg, err_buf);
}
void logmsgf(log_lvl_t level, const char *restrict format, ...) {
@@ -83,7 +85,7 @@ void logmsgf(log_lvl_t level, const char *restrict format, ...) {
if (!logger_alive) {
// no logger thread running
// simply write to stdout without synchronization
printf("%s[%-6s][%-6s]%s%s ", color, (name != NULL) ? (char *) name : "", level_keywords[level], CLR_STR, (prefix != NULL) ? (char *) prefix : "");
printf("%s" LOG_PREFIX "%s%s ", color, (name != NULL) ? (char *) name : "", level_keywords[level], CLR_STR, (prefix != NULL) ? (char *) prefix : "");
vprintf(buf, args);
printf("\n");
} else {
@@ -212,7 +214,7 @@ static void *logger_thread(void *arg) {
log_msg_t *msg = &buffer.msgs[buffer.wr];
buffer.wr = (buffer.wr + 1) % LOG_BUF_SIZE;
printf("%s[%-6s][%-6s]%s%s %s\n",
printf("%s" LOG_PREFIX "%s%s %s\n",
(msg->lvl <= LOG_ERROR) ? ERR_STR : ((msg->lvl <= LOG_WARNING) ? WRN_STR : ""),
(msg->name[0] != 0) ? (char *) msg->name : "", level_keywords[msg->lvl], CLR_STR,
(msg->prefix[0] != 0) ? (char *) msg->prefix : "", msg->txt);

View File

@@ -11,12 +11,10 @@
#include "client.h"
#include "logger.h"
#include "lib/cache.h"
#include "cache_handler.h"
#include "lib/config.h"
#include "lib/sock.h"
#include "lib/proxy.h"
#include "lib/geoip.h"
#include "lib/utils.h"
#include <stdio.h>
#include <getopt.h>
@@ -38,14 +36,14 @@ volatile sig_atomic_t alive = 1;
const char *config_file;
static int sockets[NUM_SOCKETS];
static sock clients[MAX_CHILDREN];
static pthread_t children[MAX_CHILDREN];
static SSL_CTX *contexts[CONFIG_MAX_CERT_CONFIG];
static client_ctx_t clients[MAX_CLIENTS];
static int clean() {
remove("/var/sesimos/server/cache");
rmdir("/var/sesimos/server/");
return 0;
}
@@ -200,7 +198,7 @@ int main(int argc, char *const argv[]) {
signal(SIGINT, terminate_gracefully);
signal(SIGTERM, terminate_gracefully);
if ((ret = geoip_init(geoip_dir)) != 0) {
if ((ret = geoip_init(config.geoip_dir)) != 0) {
if (ret == -1) {
critical("Unable to initialize geoip");
}
@@ -271,7 +269,8 @@ int main(int argc, char *const argv[]) {
for (j = 0; j < MAX_CHILDREN; j++) {
if (children[j] == 0) break;
}
sock *client = &clients[j];
client_ctx_t *client_ctx = &clients[j];
sock *client = &client_ctx->socket;
client->ctx = contexts[0];
socklen_t addr_len = sizeof(client->addr);

View File

@@ -20,6 +20,7 @@
#define CLIENT_TIMEOUT 3600
#define SERVER_TIMEOUT_INIT 4
#define SERVER_TIMEOUT 3600
#define MAX_CLIENTS 4096
#define CNX_HANDLER_WORKERS 8
#define REQ_HANDLER_WORKERS 16