Compare commits
	
		
			4 Commits
		
	
	
		
			2efe65fc74
			...
			7653c3117e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						
						
							
						
						7653c3117e
	
				 | 
					
					
						|||
| 
						
						
							
						
						483b386100
	
				 | 
					
					
						|||
| 
						
						
							
						
						bfa9cf4fcd
	
				 | 
					
					
						|||
| 
						
						
							
						
						9ac67dbfd3
	
				 | 
					
					
						
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -7,4 +7,4 @@
 | 
				
			|||||||
!test/**
 | 
					!test/**
 | 
				
			||||||
!Makefile
 | 
					!Makefile
 | 
				
			||||||
!.gitignore
 | 
					!.gitignore
 | 
				
			||||||
!README.md
 | 
					!*.md
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								architecture.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								architecture.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					# Architecture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* logger (1)
 | 
				
			||||||
 | 
					* listener (2) - 80, 443
 | 
				
			||||||
 | 
					* cache_handler (1)
 | 
				
			||||||
 | 
					* connection_initializer
 | 
				
			||||||
 | 
					* request_handler
 | 
				
			||||||
 | 
					* local_handler
 | 
				
			||||||
 | 
					* rev_proxy_handler
 | 
				
			||||||
 | 
					* ws_handler
 | 
				
			||||||
 | 
					* fastcgi_handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* -> logger
 | 
				
			||||||
 | 
					* main -> listener
 | 
				
			||||||
 | 
					* listener -> connection_handler
 | 
				
			||||||
 | 
					* connection_initializer -> request_handler
 | 
				
			||||||
 | 
					* request_handler -> local_handler -> request_handler
 | 
				
			||||||
 | 
					* local_handler -> fastcgi_handler -> request_handler
 | 
				
			||||||
 | 
					* request_handler -> rp_handler -> request_handler
 | 
				
			||||||
 | 
					* rev_proxy_handler -> ws_handler -> request_handler
 | 
				
			||||||
							
								
								
									
										98
									
								
								src/client.c
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								src/client.c
									
									
									
									
									
								
							@@ -34,9 +34,6 @@
 | 
				
			|||||||
volatile sig_atomic_t server_keep_alive = 1;
 | 
					volatile sig_atomic_t server_keep_alive = 1;
 | 
				
			||||||
struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
 | 
					struct timeval client_timeout = {.tv_sec = CLIENT_TIMEOUT, .tv_usec = 0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip;
 | 
					 | 
				
			||||||
char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
host_config *get_host_config(const char *host) {
 | 
					host_config *get_host_config(const char *host) {
 | 
				
			||||||
    for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) {
 | 
					    for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) {
 | 
				
			||||||
        host_config *hc = &config->hosts[i];
 | 
					        host_config *hc = &config->hosts[i];
 | 
				
			||||||
@@ -54,7 +51,7 @@ void client_terminate(int _) {
 | 
				
			|||||||
    server_keep_alive = 0;
 | 
					    server_keep_alive = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int client_request_handler(sock *client, unsigned long client_num, unsigned int req_num) {
 | 
					int client_request_handler(client_ctx_t *cctx, sock *client, unsigned long client_num, unsigned int req_num, const char *restrict log_client_prefix) {
 | 
				
			||||||
    struct timespec begin, end;
 | 
					    struct timespec begin, end;
 | 
				
			||||||
    long ret;
 | 
					    long ret;
 | 
				
			||||||
    int client_keep_alive;
 | 
					    int client_keep_alive;
 | 
				
			||||||
@@ -65,6 +62,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
 | 
				
			|||||||
    char buffer[CHUNK_SIZE];
 | 
					    char buffer[CHUNK_SIZE];
 | 
				
			||||||
    char host[256];
 | 
					    char host[256];
 | 
				
			||||||
    const char *host_ptr, *hdr_connection;
 | 
					    const char *host_ptr, *hdr_connection;
 | 
				
			||||||
 | 
					    char log_req_prefix[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    msg_buf[0] = 0;
 | 
					    msg_buf[0] = 0;
 | 
				
			||||||
    err_msg[0] = 0;
 | 
					    err_msg[0] = 0;
 | 
				
			||||||
@@ -79,7 +77,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
 | 
				
			|||||||
    int use_rev_proxy = 0;
 | 
					    int use_rev_proxy = 0;
 | 
				
			||||||
    int p_len;
 | 
					    int p_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fastcgi_conn fcgi_conn = {.socket = 0, .req_id = 0};
 | 
					    fastcgi_conn fcgi_conn = {.socket = 0, .req_id = 0, .ctx = cctx};
 | 
				
			||||||
    http_status custom_status;
 | 
					    http_status custom_status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    http_res res = {.version = "1.1", .status = http_get_status(501), .hdr.field_num = 0, .hdr.last_field_num = -1};
 | 
					    http_res res = {.version = "1.1", .status = http_get_status(501), .hdr.field_num = 0, .hdr.last_field_num = -1};
 | 
				
			||||||
@@ -130,10 +128,10 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
 | 
				
			|||||||
        sprintf(err_msg, "Host header field is too long.");
 | 
					        sprintf(err_msg, "Host header field is too long.");
 | 
				
			||||||
        goto respond;
 | 
					        goto respond;
 | 
				
			||||||
    } else if (host_ptr == NULL || strchr(host_ptr, '/') != NULL) {
 | 
					    } else if (host_ptr == NULL || strchr(host_ptr, '/') != NULL) {
 | 
				
			||||||
        if (strchr(client_addr_str, ':') == NULL) {
 | 
					        if (strchr(cctx->addr, ':') == NULL) {
 | 
				
			||||||
            strcpy(host, client_addr_str);
 | 
					            strcpy(host, cctx->addr);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            sprintf(host, "[%s]", client_addr_str);
 | 
					            sprintf(host, "[%s]", cctx->addr);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        res.status = http_get_status(400);
 | 
					        res.status = http_get_status(400);
 | 
				
			||||||
        sprintf(err_msg, "The client provided no or an invalid Host header field.");
 | 
					        sprintf(err_msg, "The client provided no or an invalid Host header field.");
 | 
				
			||||||
@@ -480,7 +478,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
 | 
				
			|||||||
        http_remove_header_field(&res.hdr, "Date", HTTP_REMOVE_ALL);
 | 
					        http_remove_header_field(&res.hdr, "Date", HTTP_REMOVE_ALL);
 | 
				
			||||||
        http_remove_header_field(&res.hdr, "Server", HTTP_REMOVE_ALL);
 | 
					        http_remove_header_field(&res.hdr, "Server", HTTP_REMOVE_ALL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ret = rev_proxy_init(&req, &res, &ctx, conf, client, &custom_status, err_msg);
 | 
					        ret = rev_proxy_init(&req, &res, &ctx, conf, client, cctx, &custom_status, err_msg);
 | 
				
			||||||
        use_rev_proxy = (ret == 0);
 | 
					        use_rev_proxy = (ret == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (res.status->code == 101) {
 | 
					        if (res.status->code == 101) {
 | 
				
			||||||
@@ -722,7 +720,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int
 | 
				
			|||||||
    return !client_keep_alive;
 | 
					    return !client_keep_alive;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int client_connection_handler(sock *client, unsigned long client_num) {
 | 
					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) {
 | 
				
			||||||
    struct timespec begin, end;
 | 
					    struct timespec begin, end;
 | 
				
			||||||
    int ret, req_num;
 | 
					    int ret, req_num;
 | 
				
			||||||
    char buf[1024];
 | 
					    char buf[1024];
 | 
				
			||||||
@@ -730,7 +728,7 @@ int client_connection_handler(sock *client, unsigned long client_num) {
 | 
				
			|||||||
    clock_gettime(CLOCK_MONOTONIC, &begin);
 | 
					    clock_gettime(CLOCK_MONOTONIC, &begin);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (dns_server[0] != 0) {
 | 
					    if (dns_server[0] != 0) {
 | 
				
			||||||
        sprintf(buf, "dig @%s +short +time=1 -x %s", dns_server, client_addr_str);
 | 
					        sprintf(buf, "dig @%s +short +time=1 -x %s", dns_server, ctx->addr);
 | 
				
			||||||
        FILE *dig = popen(buf, "r");
 | 
					        FILE *dig = popen(buf, "r");
 | 
				
			||||||
        if (dig == NULL) {
 | 
					        if (dig == NULL) {
 | 
				
			||||||
            error("Unable to start dig: %s", strerror(errno));
 | 
					            error("Unable to start dig: %s", strerror(errno));
 | 
				
			||||||
@@ -747,18 +745,16 @@ int client_connection_handler(sock *client, unsigned long client_num) {
 | 
				
			|||||||
            goto dig_err;
 | 
					            goto dig_err;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        ptr[-1] = 0;
 | 
					        ptr[-1] = 0;
 | 
				
			||||||
        client_host_str = malloc(strlen(buf) + 1);
 | 
					        strncpy(ctx->host, buf, sizeof(ctx->host));
 | 
				
			||||||
        strcpy(client_host_str, buf);
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        dig_err:
 | 
					        dig_err:
 | 
				
			||||||
        client_host_str = NULL;
 | 
					        ctx->host[0] = 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client_geoip = malloc(GEOIP_MAX_SIZE);
 | 
					 | 
				
			||||||
    long str_off = 0;
 | 
					    long str_off = 0;
 | 
				
			||||||
    for (int i = 0; i < MAX_MMDB && mmdbs[i].filename != NULL; i++) {
 | 
					    for (int i = 0; i < MAX_MMDB && mmdbs[i].filename != NULL; i++) {
 | 
				
			||||||
        int gai_error, mmdb_res;
 | 
					        int gai_error, mmdb_res;
 | 
				
			||||||
        MMDB_lookup_result_s result = MMDB_lookup_string(&mmdbs[i], client_addr_str, &gai_error, &mmdb_res);
 | 
					        MMDB_lookup_result_s result = MMDB_lookup_string(&mmdbs[i], ctx->addr, &gai_error, &mmdb_res);
 | 
				
			||||||
        if (mmdb_res != MMDB_SUCCESS) {
 | 
					        if (mmdb_res != MMDB_SUCCESS) {
 | 
				
			||||||
            error("Unable to lookup geoip info: %s", MMDB_strerror(mmdb_res));
 | 
					            error("Unable to lookup geoip info: %s", MMDB_strerror(mmdb_res));
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
@@ -780,32 +776,30 @@ int client_connection_handler(sock *client, unsigned long client_num) {
 | 
				
			|||||||
        if (str_off != 0) {
 | 
					        if (str_off != 0) {
 | 
				
			||||||
            str_off--;
 | 
					            str_off--;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        mmdb_json(list, client_geoip, &str_off, GEOIP_MAX_SIZE);
 | 
					        mmdb_json(list, ctx->geoip, &str_off, GEOIP_MAX_SIZE);
 | 
				
			||||||
        if (prev != 0) {
 | 
					        if (prev != 0) {
 | 
				
			||||||
            client_geoip[prev - 1] = ',';
 | 
					            ctx->geoip[prev - 1] = ',';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MMDB_free_entry_data_list(list);
 | 
					        MMDB_free_entry_data_list(list);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char client_cc[3];
 | 
					    ctx->cc[0] = 0;
 | 
				
			||||||
    client_cc[0] = 0;
 | 
					 | 
				
			||||||
    if (str_off == 0) {
 | 
					    if (str_off == 0) {
 | 
				
			||||||
        free(client_geoip);
 | 
					        ctx->geoip[0] = 0;
 | 
				
			||||||
        client_geoip = NULL;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        char *pos = client_geoip;
 | 
					        const char *pos = ctx->geoip;
 | 
				
			||||||
        pos = strstr(pos, "\"country\":");
 | 
					        pos = strstr(pos, "\"country\":");
 | 
				
			||||||
        if (pos != NULL) {
 | 
					        if (pos != NULL) {
 | 
				
			||||||
            pos = strstr(pos, "\"iso_code\":");
 | 
					            pos = strstr(pos, "\"iso_code\":");
 | 
				
			||||||
            pos += 12;
 | 
					            pos += 12;
 | 
				
			||||||
            snprintf(client_cc, sizeof(client_cc), "%s", pos);
 | 
					            snprintf(ctx->cc, sizeof(ctx->cc), "%s", pos);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info("Connection accepted from %s %s%s%s[%s]", client_addr_str, client_host_str != NULL ? "(" : "",
 | 
					    info("Connection accepted from %s %s%s%s[%s]", ctx->addr, ctx->host[0] != 0 ? "(" : "",
 | 
				
			||||||
         client_host_str != NULL ? client_host_str : "", client_host_str != NULL ? ") " : "",
 | 
					         ctx->host[0] != 0 ? ctx->host : "", ctx->host[0] != 0 ? ") " : "",
 | 
				
			||||||
         client_cc[0] != 0 ? client_cc : "N/A");
 | 
					         ctx->cc[0] != 0 ? ctx->cc : "N/A");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client_timeout.tv_sec = CLIENT_TIMEOUT;
 | 
					    client_timeout.tv_sec = CLIENT_TIMEOUT;
 | 
				
			||||||
    client_timeout.tv_usec = 0;
 | 
					    client_timeout.tv_usec = 0;
 | 
				
			||||||
@@ -836,7 +830,7 @@ int client_connection_handler(sock *client, unsigned long client_num) {
 | 
				
			|||||||
    req_num = 0;
 | 
					    req_num = 0;
 | 
				
			||||||
    ret = 0;
 | 
					    ret = 0;
 | 
				
			||||||
    while (ret == 0 && server_keep_alive && req_num < REQ_PER_CONNECTION) {
 | 
					    while (ret == 0 && server_keep_alive && req_num < REQ_PER_CONNECTION) {
 | 
				
			||||||
        ret = client_request_handler(client, client_num, req_num++);
 | 
					        ret = client_request_handler(ctx, client, client_num, req_num++, log_client_prefix);
 | 
				
			||||||
        logger_set_prefix(log_conn_prefix);
 | 
					        logger_set_prefix(log_conn_prefix);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -856,62 +850,42 @@ int client_connection_handler(sock *client, unsigned long client_num) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 *client_addr) {
 | 
					int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 *client_addr) {
 | 
				
			||||||
    int ret;
 | 
					 | 
				
			||||||
    struct sockaddr_in6 *server_addr;
 | 
					    struct sockaddr_in6 *server_addr;
 | 
				
			||||||
    struct sockaddr_storage server_addr_storage;
 | 
					    struct sockaddr_storage server_addr_storage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    client_ctx_t ctx;
 | 
				
			||||||
 | 
					    char log_client_prefix[256], log_conn_prefix[512];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    char *color_table[] = {"\x1B[31m", "\x1B[32m", "\x1B[33m", "\x1B[34m", "\x1B[35m", "\x1B[36m"};
 | 
					    char *color_table[] = {"\x1B[31m", "\x1B[32m", "\x1B[33m", "\x1B[34m", "\x1B[35m", "\x1B[36m"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    signal(SIGINT, client_terminate);
 | 
					    signal(SIGINT, client_terminate);
 | 
				
			||||||
    signal(SIGTERM, client_terminate);
 | 
					    signal(SIGTERM, client_terminate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    client_addr_str_ptr = malloc(INET6_ADDRSTRLEN);
 | 
					    inet_ntop(client_addr->sin6_family, (void *) &client_addr->sin6_addr, ctx._c_addr, sizeof(ctx._c_addr));
 | 
				
			||||||
    inet_ntop(client_addr->sin6_family, (void *) &client_addr->sin6_addr, client_addr_str_ptr, INET6_ADDRSTRLEN);
 | 
					    if (strncmp(ctx._c_addr, "::ffff:", 7) == 0) {
 | 
				
			||||||
    if (strncmp(client_addr_str_ptr, "::ffff:", 7) == 0) {
 | 
					        ctx.addr = ctx._c_addr + 7;
 | 
				
			||||||
        client_addr_str = client_addr_str_ptr + 7;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        client_addr_str = client_addr_str_ptr;
 | 
					        ctx.addr = ctx._c_addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    socklen_t len = sizeof(server_addr_storage);
 | 
					    socklen_t len = sizeof(server_addr_storage);
 | 
				
			||||||
    getsockname(client->socket, (struct sockaddr *) &server_addr_storage, &len);
 | 
					    getsockname(client->socket, (struct sockaddr *) &server_addr_storage, &len);
 | 
				
			||||||
    server_addr = (struct sockaddr_in6 *) &server_addr_storage;
 | 
					    server_addr = (struct sockaddr_in6 *) &server_addr_storage;
 | 
				
			||||||
    server_addr_str_ptr = malloc(INET6_ADDRSTRLEN);
 | 
					    inet_ntop(server_addr->sin6_family, (void *) &server_addr->sin6_addr, ctx._s_addr, sizeof(ctx._s_addr));
 | 
				
			||||||
    inet_ntop(server_addr->sin6_family, (void *) &server_addr->sin6_addr, server_addr_str_ptr, INET6_ADDRSTRLEN);
 | 
					    if (strncmp(ctx._s_addr, "::ffff:", 7) == 0) {
 | 
				
			||||||
    if (strncmp(server_addr_str_ptr, "::ffff:", 7) == 0) {
 | 
					        ctx.s_addr = ctx._s_addr + 7;
 | 
				
			||||||
        server_addr_str = server_addr_str_ptr + 7;
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        server_addr_str = server_addr_str_ptr;
 | 
					        ctx.s_addr = ctx._s_addr;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log_req_prefix = malloc(256);
 | 
					 | 
				
			||||||
    log_client_prefix = malloc(256);
 | 
					 | 
				
			||||||
    sprintf(log_client_prefix, "[%s%4i%s]%s[%*s][%5i]%s", (int) client->enc ? HTTPS_STR : HTTP_STR,
 | 
					    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[client_num % 6], INET6_ADDRSTRLEN, client_addr_str,
 | 
					            ntohs(server_addr->sin6_port), CLR_STR, color_table[client_num % 6], INET6_ADDRSTRLEN, ctx.addr,
 | 
				
			||||||
            ntohs(client_addr->sin6_port), CLR_STR);
 | 
					            ntohs(client_addr->sin6_port), CLR_STR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    log_conn_prefix = malloc(256);
 | 
					    sprintf(log_conn_prefix, "[%6i][%*s]%s", getpid(), INET6_ADDRSTRLEN, ctx.s_addr, log_client_prefix);
 | 
				
			||||||
    sprintf(log_conn_prefix, "[%6i][%*s]%s", getpid(), INET6_ADDRSTRLEN, server_addr_str, log_client_prefix);
 | 
					 | 
				
			||||||
    logger_set_prefix(log_conn_prefix);
 | 
					    logger_set_prefix(log_conn_prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info("Started child process with PID %i", getpid());
 | 
					    info("Started child process with PID %i", getpid());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = client_connection_handler(client, client_num);
 | 
					    return client_connection_handler(&ctx, client, client_num, log_conn_prefix, log_client_prefix);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    free(client_addr_str_ptr);
 | 
					 | 
				
			||||||
    client_addr_str_ptr = NULL;
 | 
					 | 
				
			||||||
    free(server_addr_str_ptr);
 | 
					 | 
				
			||||||
    server_addr_str_ptr = NULL;
 | 
					 | 
				
			||||||
    if (client_host_str != NULL) {
 | 
					 | 
				
			||||||
        free(client_host_str);
 | 
					 | 
				
			||||||
        client_host_str = NULL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    free(log_conn_prefix);
 | 
					 | 
				
			||||||
    log_conn_prefix = NULL;
 | 
					 | 
				
			||||||
    free(log_req_prefix);
 | 
					 | 
				
			||||||
    log_req_prefix = NULL;
 | 
					 | 
				
			||||||
    free(log_client_prefix);
 | 
					 | 
				
			||||||
    log_client_prefix = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return ret;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								src/client.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/client.h
									
									
									
									
									
								
							@@ -11,9 +11,20 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "lib/config.h"
 | 
					#include "lib/config.h"
 | 
				
			||||||
#include "lib/sock.h"
 | 
					#include "lib/sock.h"
 | 
				
			||||||
 | 
					#include "lib/geoip.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    char *addr;
 | 
				
			||||||
 | 
					    char *s_addr;
 | 
				
			||||||
 | 
					    char cc[3];
 | 
				
			||||||
 | 
					    char host[256];
 | 
				
			||||||
 | 
					    char geoip[GEOIP_MAX_SIZE + 1];
 | 
				
			||||||
 | 
					    char _c_addr[INET6_ADDRSTRLEN + 1];
 | 
				
			||||||
 | 
					    char _s_addr[INET6_ADDRSTRLEN + 1];
 | 
				
			||||||
 | 
					} client_ctx_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
host_config *get_host_config(const char *host);
 | 
					host_config *get_host_config(const char *host);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 *client_addr);
 | 
					int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 *client_addr);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,8 +53,7 @@ char *fastcgi_add_param(char *buf, const char *key, const char *value) {
 | 
				
			|||||||
    return ptr;
 | 
					    return ptr;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int fastcgi_init(fastcgi_conn *conn, int mode, unsigned int client_num, unsigned int req_num, const sock *client,
 | 
					int fastcgi_init(fastcgi_conn *conn, int mode, unsigned int client_num, unsigned int req_num, const sock *client, const http_req *req, const http_uri *uri) {
 | 
				
			||||||
                 const http_req *req, const http_uri *uri) {
 | 
					 | 
				
			||||||
    unsigned short req_id = (client_num & 0xFFF) << 4;
 | 
					    unsigned short req_id = (client_num & 0xFFF) << 4;
 | 
				
			||||||
    if (client_num == 0) {
 | 
					    if (client_num == 0) {
 | 
				
			||||||
        req_id |= (req_num + 1) & 0xF;
 | 
					        req_id |= (req_num + 1) & 0xF;
 | 
				
			||||||
@@ -133,8 +132,8 @@ int fastcgi_init(fastcgi_conn *conn, int mode, unsigned int client_num, unsigned
 | 
				
			|||||||
    addr = (struct sockaddr_in6 *) &addr_storage;
 | 
					    addr = (struct sockaddr_in6 *) &addr_storage;
 | 
				
			||||||
    sprintf(buf0, "%i", addr->sin6_port);
 | 
					    sprintf(buf0, "%i", addr->sin6_port);
 | 
				
			||||||
    param_ptr = fastcgi_add_param(param_ptr, "REMOTE_PORT", buf0);
 | 
					    param_ptr = fastcgi_add_param(param_ptr, "REMOTE_PORT", buf0);
 | 
				
			||||||
    param_ptr = fastcgi_add_param(param_ptr, "REMOTE_ADDR", client_addr_str);
 | 
					    param_ptr = fastcgi_add_param(param_ptr, "REMOTE_ADDR", conn->ctx->addr);
 | 
				
			||||||
    param_ptr = fastcgi_add_param(param_ptr, "REMOTE_HOST", client_host_str != NULL ? client_host_str : client_addr_str);
 | 
					    param_ptr = fastcgi_add_param(param_ptr, "REMOTE_HOST", conn->ctx->host[0] != 0 ? conn->ctx->host : conn->ctx->addr);
 | 
				
			||||||
    //param_ptr = fastcgi_add_param(param_ptr, "REMOTE_IDENT", "");
 | 
					    //param_ptr = fastcgi_add_param(param_ptr, "REMOTE_IDENT", "");
 | 
				
			||||||
    //param_ptr = fastcgi_add_param(param_ptr, "REMOTE_USER", "");
 | 
					    //param_ptr = fastcgi_add_param(param_ptr, "REMOTE_USER", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -157,8 +156,8 @@ 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 : "");
 | 
					    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");
 | 
					    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 : "");
 | 
					    param_ptr = fastcgi_add_param(param_ptr, "CONTENT_TYPE", content_type != NULL ? content_type : "");
 | 
				
			||||||
    if (client_geoip != NULL) {
 | 
					    if (conn->ctx->geoip[0] != 0) {
 | 
				
			||||||
        param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", client_geoip);
 | 
					        param_ptr = fastcgi_add_param(param_ptr, "REMOTE_INFO", conn->ctx->geoip);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < req->hdr.field_num; i++) {
 | 
					    for (int i = 0; i < req->hdr.field_num; i++) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,7 @@
 | 
				
			|||||||
#include "include/fastcgi.h"
 | 
					#include "include/fastcgi.h"
 | 
				
			||||||
#include "http.h"
 | 
					#include "http.h"
 | 
				
			||||||
#include "uri.h"
 | 
					#include "uri.h"
 | 
				
			||||||
 | 
					#include "../client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FASTCGI_CHUNKED 1
 | 
					#define FASTCGI_CHUNKED 1
 | 
				
			||||||
#define FASTCGI_COMPRESS_GZ 2
 | 
					#define FASTCGI_COMPRESS_GZ 2
 | 
				
			||||||
@@ -36,6 +37,7 @@ typedef struct {
 | 
				
			|||||||
    const char *webroot;
 | 
					    const char *webroot;
 | 
				
			||||||
    unsigned short out_len;
 | 
					    unsigned short out_len;
 | 
				
			||||||
    unsigned short out_off;
 | 
					    unsigned short out_off;
 | 
				
			||||||
 | 
					    client_ctx_t *ctx;
 | 
				
			||||||
} fastcgi_conn;
 | 
					} fastcgi_conn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
char *fastcgi_add_param(char *buf, const char *key, const char *value);
 | 
					char *fastcgi_add_param(char *buf, const char *key, const char *value);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,7 @@ int rev_proxy_preload(void) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_request_header(http_req *req, int enc) {
 | 
					int rev_proxy_request_header(http_req *req, int enc, client_ctx_t *ctx) {
 | 
				
			||||||
    char buf1[256], buf2[256];
 | 
					    char buf1[256], buf2[256];
 | 
				
			||||||
    int p_len;
 | 
					    int p_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,12 +50,12 @@ int rev_proxy_request_header(http_req *req, int enc) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const char *host = http_get_header_field(&req->hdr, "Host");
 | 
					    const char *host = http_get_header_field(&req->hdr, "Host");
 | 
				
			||||||
    const char *forwarded = http_get_header_field(&req->hdr, "Forwarded");
 | 
					    const char *forwarded = http_get_header_field(&req->hdr, "Forwarded");
 | 
				
			||||||
    int client_ipv6 = strchr(client_addr_str, ':') != NULL;
 | 
					    int client_ipv6 = strchr(ctx->addr, ':') != NULL;
 | 
				
			||||||
    int server_ipv6 = strchr(server_addr_str, ':') != NULL;
 | 
					    int server_ipv6 = strchr(ctx->s_addr, ':') != NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    p_len = snprintf(buf1, sizeof(buf1), "by=%s%s%s;for=%s%s%s;host=%s;proto=%s",
 | 
					    p_len = snprintf(buf1, sizeof(buf1), "by=%s%s%s;for=%s%s%s;host=%s;proto=%s",
 | 
				
			||||||
                     server_ipv6 ? "\"[" : "", server_addr_str, server_ipv6 ? "]\"" : "",
 | 
					                     server_ipv6 ? "\"[" : "", ctx->s_addr, server_ipv6 ? "]\"" : "",
 | 
				
			||||||
                     client_ipv6 ? "\"[" : "", client_addr_str, client_ipv6 ? "]\"" : "",
 | 
					                     client_ipv6 ? "\"[" : "", ctx->addr, client_ipv6 ? "]\"" : "",
 | 
				
			||||||
                     host, enc ? "https" : "http");
 | 
					                     host, enc ? "https" : "http");
 | 
				
			||||||
    if (p_len < 0 || p_len >= sizeof(buf1)) {
 | 
					    if (p_len < 0 || p_len >= sizeof(buf1)) {
 | 
				
			||||||
        error("Appended part of header field 'Forwarded' too long");
 | 
					        error("Appended part of header field 'Forwarded' too long");
 | 
				
			||||||
@@ -76,9 +76,9 @@ int rev_proxy_request_header(http_req *req, int enc) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    const char *xff = http_get_header_field(&req->hdr, "X-Forwarded-For");
 | 
					    const char *xff = http_get_header_field(&req->hdr, "X-Forwarded-For");
 | 
				
			||||||
    if (xff == NULL) {
 | 
					    if (xff == NULL) {
 | 
				
			||||||
        http_add_header_field(&req->hdr, "X-Forwarded-For", client_addr_str);
 | 
					        http_add_header_field(&req->hdr, "X-Forwarded-For", ctx->addr);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        sprintf(buf1, "%s, %s", xff, client_addr_str);
 | 
					        sprintf(buf1, "%s, %s", xff, ctx->addr);
 | 
				
			||||||
        http_remove_header_field(&req->hdr, "X-Forwarded-For", HTTP_REMOVE_ALL);
 | 
					        http_remove_header_field(&req->hdr, "X-Forwarded-For", HTTP_REMOVE_ALL);
 | 
				
			||||||
        http_add_header_field(&req->hdr, "X-Forwarded-For", buf1);
 | 
					        http_add_header_field(&req->hdr, "X-Forwarded-For", buf1);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -180,7 +180,7 @@ int rev_proxy_response_header(http_req *req, http_res *res, host_config *conf) {
 | 
				
			|||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config *conf, sock *client, http_status *custom_status, char *err_msg) {
 | 
					int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config *conf, sock *client, client_ctx_t *cctx, http_status *custom_status, char *err_msg) {
 | 
				
			||||||
    char buffer[CHUNK_SIZE];
 | 
					    char buffer[CHUNK_SIZE];
 | 
				
			||||||
    const char *connection, *upgrade, *ws_version;
 | 
					    const char *connection, *upgrade, *ws_version;
 | 
				
			||||||
    long ret;
 | 
					    long ret;
 | 
				
			||||||
@@ -304,7 +304,7 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf
 | 
				
			|||||||
        http_add_header_field(&req->hdr, "Connection", "keep-alive");
 | 
					        http_add_header_field(&req->hdr, "Connection", "keep-alive");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ret = rev_proxy_request_header(req, (int) client->enc);
 | 
					    ret = rev_proxy_request_header(req, (int) client->enc, cctx);
 | 
				
			||||||
    if (ret != 0) {
 | 
					    if (ret != 0) {
 | 
				
			||||||
        res->status = http_get_status(500);
 | 
					        res->status = http_get_status(500);
 | 
				
			||||||
        ctx->origin = INTERNAL;
 | 
					        ctx->origin = INTERNAL;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,17 +20,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "http.h"
 | 
					#include "http.h"
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
 | 
					#include "../client.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern sock rev_proxy;
 | 
					extern sock rev_proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_preload(void);
 | 
					int rev_proxy_preload(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_request_header(http_req *req, int enc);
 | 
					int rev_proxy_request_header(http_req *req, int enc, client_ctx_t *ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_response_header(http_req *req, http_res *res, host_config *conf);
 | 
					int rev_proxy_response_header(http_req *req, http_res *res, host_config *conf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config *conf, sock *client,
 | 
					int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config *conf, sock *client, client_ctx_t *cctx, http_status *custom_status, char *err_msg);
 | 
				
			||||||
                   http_status *custom_status, char *err_msg);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int rev_proxy_send(sock *client, unsigned long len_to_send, int flags);
 | 
					int rev_proxy_send(sock *client, unsigned long len_to_send, int flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										46
									
								
								src/logger.c
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/logger.c
									
									
									
									
									
								
							@@ -54,6 +54,12 @@ static const char *level_keywords[] = {
 | 
				
			|||||||
        "DEBUG"
 | 
					        "DEBUG"
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void err(const char *restrict msg) {
 | 
				
			||||||
 | 
					    char err_buf[64];
 | 
				
			||||||
 | 
					    strerror_r(errno, err_buf, sizeof(err_buf));
 | 
				
			||||||
 | 
					    fprintf(stderr, ERR_STR "[%6s][logger] %s: %s" CLR_STR "\n", level_keywords[LOG_CRITICAL], msg, err_buf);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void logmsgf(log_lvl_t level, const char *restrict format, ...) {
 | 
					void logmsgf(log_lvl_t level, const char *restrict format, ...) {
 | 
				
			||||||
    char buf[256];
 | 
					    char buf[256];
 | 
				
			||||||
    char err_buf[64];
 | 
					    char err_buf[64];
 | 
				
			||||||
@@ -75,11 +81,10 @@ void logmsgf(log_lvl_t level, const char *restrict format, ...) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    if (!logger_alive) {
 | 
					    if (!logger_alive) {
 | 
				
			||||||
        // no logger thread running
 | 
					        // no logger thread running
 | 
				
			||||||
        // simply write to stdout/stderr without synchronization
 | 
					        // simply write to stdout without synchronization
 | 
				
			||||||
        FILE *out = (level <= LOG_CRITICAL) ? stderr : stdout;
 | 
					        printf("%s[%-6s][%-6s]%s%s ", color, level_keywords[level], (name != NULL) ? (char *) name : "", CLR_STR, (prefix != NULL) ? (char *) prefix : "");
 | 
				
			||||||
        fprintf(out, "%s[%-6s][%-6s]%s%s ", color, level_keywords[level], (name != NULL) ? (char *) name : "", CLR_STR, (prefix != NULL) ? (char *) prefix : "");
 | 
					        vprintf(buf, args);
 | 
				
			||||||
        vfprintf(out, buf, args);
 | 
					        printf("\n");
 | 
				
			||||||
        fprintf(out, "\n");
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        // wait for free slot in buffer
 | 
					        // wait for free slot in buffer
 | 
				
			||||||
        try_again_free:
 | 
					        try_again_free:
 | 
				
			||||||
@@ -87,8 +92,7 @@ void logmsgf(log_lvl_t level, const char *restrict format, ...) {
 | 
				
			|||||||
            if (errno == EINTR) {
 | 
					            if (errno == EINTR) {
 | 
				
			||||||
                goto try_again_free;
 | 
					                goto try_again_free;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                strerror_r(errno, err_buf, sizeof(err_buf));
 | 
					                err("Unable to lock semaphore");
 | 
				
			||||||
                fprintf(stderr, "[logger] " ERR_STR "Unable to lock semaphore: %s" CLR_STR "\n", err_buf);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // cleanup
 | 
					            // cleanup
 | 
				
			||||||
            va_end(args);
 | 
					            va_end(args);
 | 
				
			||||||
@@ -101,8 +105,7 @@ void logmsgf(log_lvl_t level, const char *restrict format, ...) {
 | 
				
			|||||||
            if (errno == EINTR) {
 | 
					            if (errno == EINTR) {
 | 
				
			||||||
                goto try_again_buf;
 | 
					                goto try_again_buf;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                strerror_r(errno, err_buf, sizeof(err_buf));
 | 
					                err("Unable to lock semaphore");
 | 
				
			||||||
                fprintf(stderr, "[logger] " ERR_STR "Unable to lock semaphore: %s" CLR_STR "\n", err_buf);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            // cleanup
 | 
					            // cleanup
 | 
				
			||||||
            sem_post(&sem_buf_free);
 | 
					            sem_post(&sem_buf_free);
 | 
				
			||||||
@@ -147,13 +150,11 @@ static void logger_destroy(void) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int logger_init(void) {
 | 
					static int logger_init(void) {
 | 
				
			||||||
    char err_buf[64];
 | 
					 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // try to initialize all three semaphores
 | 
					    // try to initialize all three semaphores
 | 
				
			||||||
    if (sem_init(&sem_buf, 0, 1) != 0 || sem_init(&sem_buf_free, 0, 1) != 0 || sem_init(&sem_buf_used, 0, 0) != 0) {
 | 
					    if (sem_init(&sem_buf, 0, 1) != 0 || sem_init(&sem_buf_free, 0, 1) != 0 || sem_init(&sem_buf_used, 0, 0) != 0) {
 | 
				
			||||||
        strerror_r(errno, err_buf, sizeof(err_buf));
 | 
					        err("Unable to initialize semaphore");
 | 
				
			||||||
        fprintf(stderr, "[logger] " ERR_STR "Unable to initialize semaphore: %s" CLR_STR "\n", err_buf);
 | 
					 | 
				
			||||||
        logger_destroy();
 | 
					        logger_destroy();
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -164,8 +165,8 @@ static int logger_init(void) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // initialize thread specific values (keys)
 | 
					    // initialize thread specific values (keys)
 | 
				
			||||||
    if ((ret = pthread_key_create(&key_name, free)) != 0 || (ret = pthread_key_create(&key_prefix, free)) != 0) {
 | 
					    if ((ret = pthread_key_create(&key_name, free)) != 0 || (ret = pthread_key_create(&key_prefix, free)) != 0) {
 | 
				
			||||||
        strerror_r(ret, err_buf, sizeof(err_buf));
 | 
					        errno = ret;
 | 
				
			||||||
        fprintf(stderr, "[logger] " ERR_STR "Unable to initialize thread specific values: %s" CLR_STR "\n", err_buf);
 | 
					        err("Unable to initialize thread specific values");
 | 
				
			||||||
        logger_destroy();
 | 
					        logger_destroy();
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -184,14 +185,13 @@ void logger_set_name(const char *restrict name) {
 | 
				
			|||||||
        // not initialized
 | 
					        // not initialized
 | 
				
			||||||
        strncpy(global_name, name, sizeof(global_name));
 | 
					        strncpy(global_name, name, sizeof(global_name));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        char err_buf[64];
 | 
					 | 
				
			||||||
        int ret;
 | 
					        int ret;
 | 
				
			||||||
        void *ptr = pthread_getspecific(key_name);
 | 
					        void *ptr = pthread_getspecific(key_name);
 | 
				
			||||||
        if (!ptr) {
 | 
					        if (!ptr) {
 | 
				
			||||||
            ptr = malloc(LOG_NAME_LEN);
 | 
					            ptr = malloc(LOG_NAME_LEN);
 | 
				
			||||||
            if ((ret = pthread_setspecific(key_name, ptr)) != 0) {
 | 
					            if ((ret = pthread_setspecific(key_name, ptr)) != 0) {
 | 
				
			||||||
                strerror_r(ret, err_buf, sizeof(err_buf));
 | 
					                errno = ret;
 | 
				
			||||||
                fprintf(stderr, "[logger] " ERR_STR "Unable to set thread specific values: %s" CLR_STR "\n", err_buf);
 | 
					                err("Unable to set thread specific values");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -203,15 +203,14 @@ void logger_set_prefix(const char *restrict prefix) {
 | 
				
			|||||||
    if (key_name == -1) {
 | 
					    if (key_name == -1) {
 | 
				
			||||||
        strncpy(global_prefix, prefix, sizeof(global_prefix));
 | 
					        strncpy(global_prefix, prefix, sizeof(global_prefix));
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        char err_buf[64];
 | 
					 | 
				
			||||||
        int ret;
 | 
					        int ret;
 | 
				
			||||||
        void *ptr = pthread_getspecific(key_name);
 | 
					        void *ptr = pthread_getspecific(key_name);
 | 
				
			||||||
        if (!ptr) {
 | 
					        if (!ptr) {
 | 
				
			||||||
            ptr = malloc(LOG_PREFIX_LEN);
 | 
					            ptr = malloc(LOG_PREFIX_LEN);
 | 
				
			||||||
            pthread_setspecific(key_prefix, ptr);
 | 
					            pthread_setspecific(key_prefix, ptr);
 | 
				
			||||||
            if ((ret = pthread_setspecific(key_prefix, ptr)) != 0) {
 | 
					            if ((ret = pthread_setspecific(key_prefix, ptr)) != 0) {
 | 
				
			||||||
                strerror_r(ret, err_buf, sizeof(err_buf));
 | 
					                errno = ret;
 | 
				
			||||||
                fprintf(stderr, "[logger] " ERR_STR "Unable to set thread specific values: %s" CLR_STR "\n", err_buf);
 | 
					                err("Unable to set thread specific values");
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -224,8 +223,6 @@ void logger_stop(void) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void logger(void) {
 | 
					void logger(void) {
 | 
				
			||||||
    char err_buf[64];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (logger_init() != 0)
 | 
					    if (logger_init() != 0)
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -238,8 +235,7 @@ void logger(void) {
 | 
				
			|||||||
            if (errno == EINTR) {
 | 
					            if (errno == EINTR) {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                strerror_r(errno, err_buf, sizeof(err_buf));
 | 
					                err("Unable to lock semaphore");
 | 
				
			||||||
                fprintf(stderr, "[logger] " ERR_STR "Unable to lock semaphore: %s" CLR_STR "\n", err_buf);
 | 
					 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -247,7 +243,7 @@ void logger(void) {
 | 
				
			|||||||
        log_msg_t *msg = &buffer.msgs[buffer.wr];
 | 
					        log_msg_t *msg = &buffer.msgs[buffer.wr];
 | 
				
			||||||
        buffer.wr = (buffer.wr + 1) % LOG_BUF_SIZE;
 | 
					        buffer.wr = (buffer.wr + 1) % LOG_BUF_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fprintf((msg->lvl <= LOG_CRITICAL) ? stderr : stdout, "[%s]%s %s\n", msg->name, (msg->prefix[0] != 0) ? msg->prefix : "", msg->txt);
 | 
					        printf("[%s]%s %s\n", msg->name, (msg->prefix[0] != 0) ? msg->prefix : "", msg->txt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // unlock slot in buffer
 | 
					        // unlock slot in buffer
 | 
				
			||||||
        sem_post(&sem_buf_free);
 | 
					        sem_post(&sem_buf_free);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								src/server.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/server.c
									
									
									
									
									
								
							@@ -51,8 +51,8 @@ static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) {
 | 
				
			|||||||
    return SSL_TLSEXT_ERR_OK;
 | 
					    return SSL_TLSEXT_ERR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void destroy(int _) {
 | 
					void destroy(int sig) {
 | 
				
			||||||
    error("Terminating forcefully!");
 | 
					    critical("Terminating forcefully!");
 | 
				
			||||||
    int status = 0;
 | 
					    int status = 0;
 | 
				
			||||||
    int ret;
 | 
					    int ret;
 | 
				
			||||||
    int kills = 0;
 | 
					    int kills = 0;
 | 
				
			||||||
@@ -60,11 +60,11 @@ void destroy(int _) {
 | 
				
			|||||||
        if (children[i] != 0) {
 | 
					        if (children[i] != 0) {
 | 
				
			||||||
            ret = waitpid(children[i], &status, WNOHANG);
 | 
					            ret = waitpid(children[i], &status, WNOHANG);
 | 
				
			||||||
            if (ret < 0) {
 | 
					            if (ret < 0) {
 | 
				
			||||||
                critical("Unable to wait for child process (PID %i)", children[i]);
 | 
					                error("Unable to wait for child process (PID %i)", children[i]);
 | 
				
			||||||
            } else if (ret == children[i]) {
 | 
					            } else if (ret == children[i]) {
 | 
				
			||||||
                children[i] = 0;
 | 
					                children[i] = 0;
 | 
				
			||||||
                if (status != 0) {
 | 
					                if (status != 0) {
 | 
				
			||||||
                    critical("Child process with PID %i terminated with exit code %i", ret, status);
 | 
					                    error("Child process with PID %i terminated with exit code %i", ret, status);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                kill(children[i], SIGKILL);
 | 
					                kill(children[i], SIGKILL);
 | 
				
			||||||
@@ -80,7 +80,7 @@ void destroy(int _) {
 | 
				
			|||||||
    exit(2);
 | 
					    exit(2);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void terminate(int _) {
 | 
					void terminate(int sig) {
 | 
				
			||||||
    fprintf(stderr, "\n");
 | 
					    fprintf(stderr, "\n");
 | 
				
			||||||
    notice("Terminating gracefully...");
 | 
					    notice("Terminating gracefully...");
 | 
				
			||||||
    active = 0;
 | 
					    active = 0;
 | 
				
			||||||
@@ -114,7 +114,7 @@ void terminate(int _) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (wait_num > 0) {
 | 
					    if (wait_num > 0) {
 | 
				
			||||||
        info("Waiting for %i child process(es)...", wait_num);
 | 
					        notice("Waiting for %i child process(es)...", wait_num);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (int i = 0; i < MAX_CHILDREN; i++) {
 | 
					    for (int i = 0; i < MAX_CHILDREN; i++) {
 | 
				
			||||||
@@ -169,8 +169,8 @@ int main(int argc, const char *argv[]) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    logger_set_name("server");
 | 
					    logger_set_name("server");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (setvbuf(stdout, NULL, _IOLBF, 0) != 0) {
 | 
					    if (setvbuf(stdout, NULL, _IOLBF, 0) != 0 || setvbuf(stderr, NULL, _IOLBF, 0) != 0) {
 | 
				
			||||||
        critical("Unable to set stdout to line-buffered mode");
 | 
					        critical("Unable to set stdout/stderr to line-buffered mode");
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    printf("Sesimos web server " SERVER_VERSION "\n");
 | 
					    printf("Sesimos web server " SERVER_VERSION "\n");
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,8 +27,6 @@ extern pid_t children[MAX_CHILDREN];
 | 
				
			|||||||
extern MMDB_s mmdbs[MAX_MMDB];
 | 
					extern MMDB_s mmdbs[MAX_MMDB];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern volatile sig_atomic_t server_keep_alive;
 | 
					extern volatile sig_atomic_t server_keep_alive;
 | 
				
			||||||
extern char *log_client_prefix, *log_conn_prefix, *log_req_prefix, *client_geoip;
 | 
					 | 
				
			||||||
extern char *client_addr_str, *client_addr_str_ptr, *server_addr_str, *server_addr_str_ptr, *client_host_str;
 | 
					 | 
				
			||||||
extern struct timeval client_timeout;
 | 
					extern struct timeval client_timeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //SESIMOS_SERVER_H
 | 
					#endif //SESIMOS_SERVER_H
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user