diff --git a/src/defs.h b/src/defs.h index 300badf..958a2f4 100644 --- a/src/defs.h +++ b/src/defs.h @@ -14,6 +14,7 @@ #define SERVER_STR_HTML "Sesimos web server " SERVER_VERSION #define CHUNK_SIZE 8192 +#define MAX_PROXY_CNX_PER_HOST 16 #ifndef DEFAULT_HOST # define DEFAULT_HOST "www.necronda.net" diff --git a/src/lib/proxy.c b/src/lib/proxy.c index b8e0582..b1a3522 100644 --- a/src/lib/proxy.c +++ b/src/lib/proxy.c @@ -12,6 +12,7 @@ #include "proxy.h" #include "utils.h" #include "compress.h" +#include "config.h" #include #include @@ -19,18 +20,55 @@ #include #include #include +#include - -sock proxy; -char *proxy_host = NULL; -struct timeval server_timeout = {.tv_sec = SERVER_TIMEOUT, .tv_usec = 0}; +static SSL_CTX *proxy_ctx = NULL; +static void *proxies = NULL; int proxy_preload(void) { - proxy.ctx = SSL_CTX_new(TLS_client_method()); + int n = 0; + for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) { + host_config_t *hc = &config.hosts[i]; + if (hc->type == CONFIG_TYPE_UNSET) break; + if (hc->type != CONFIG_TYPE_REVERSE_PROXY) continue; + n++; + } + + // FIXME return value check + proxy_ctx = SSL_CTX_new(TLS_client_method()); + proxies = malloc(n * PROXY_ARRAY_SIZE); + memset(proxies, 0, n * PROXY_ARRAY_SIZE); + return 0; } -int proxy_request_header(http_req *req, int enc, client_ctx_t *ctx) { +void proxy_unload(void) { + SSL_CTX_free(proxy_ctx); + free(proxies); +} + +static proxy_ctx_t *proxy_get_by_conf(host_config_t *conf) { + int n = 0; + for (int i = 0; i < CONFIG_MAX_HOST_CONFIG; i++) { + host_config_t *hc = &config.hosts[i]; + if (hc->type == CONFIG_TYPE_UNSET) break; + if (hc->type != CONFIG_TYPE_REVERSE_PROXY) continue; + if (hc == conf) break; + n++; + } + + void *ptr = proxies + n * PROXY_ARRAY_SIZE; + for (int i = 0; i < MAX_PROXY_CNX_PER_HOST; i++, ptr += PROXY_ARRAY_SIZE) { + proxy_ctx_t *ctx = ptr; + if (!ctx->in_use) { + return ctx; + } + } + + return NULL; +} + +int proxy_request_header(http_req *req, sock *sock) { char buf1[256], buf2[256]; int p_len; @@ -50,13 +88,13 @@ int proxy_request_header(http_req *req, int enc, client_ctx_t *ctx) { const char *host = http_get_header_field(&req->hdr, "Host"); const char *forwarded = http_get_header_field(&req->hdr, "Forwarded"); - int client_ipv6 = strchr(ctx->addr, ':') != NULL; - int server_ipv6 = strchr(ctx->s_addr, ':') != NULL; + int client_ipv6 = strchr(sock->addr, ':') != NULL; + int server_ipv6 = strchr(sock->s_addr, ':') != NULL; p_len = snprintf(buf1, sizeof(buf1), "by=%s%s%s;for=%s%s%s;host=%s;proto=%s", - server_ipv6 ? "\"[" : "", ctx->s_addr, server_ipv6 ? "]\"" : "", - client_ipv6 ? "\"[" : "", ctx->addr, client_ipv6 ? "]\"" : "", - host, enc ? "https" : "http"); + server_ipv6 ? "\"[" : "", sock->s_addr, server_ipv6 ? "]\"" : "", + client_ipv6 ? "\"[" : "", sock->addr, client_ipv6 ? "]\"" : "", + host, sock->enc ? "https" : "http"); if (p_len < 0 || p_len >= sizeof(buf1)) { error("Appended part of header field 'Forwarded' too long"); return -1; @@ -76,9 +114,9 @@ int proxy_request_header(http_req *req, int enc, client_ctx_t *ctx) { const char *xff = http_get_header_field(&req->hdr, "X-Forwarded-For"); if (xff == NULL) { - http_add_header_field(&req->hdr, "X-Forwarded-For", ctx->addr); + http_add_header_field(&req->hdr, "X-Forwarded-For", sock->addr); } else { - sprintf(buf1, "%s, %s", xff, ctx->addr); + sprintf(buf1, "%s, %s", xff, sock->addr); http_remove_header_field(&req->hdr, "X-Forwarded-For", HTTP_REMOVE_ALL); http_add_header_field(&req->hdr, "X-Forwarded-For", buf1); } @@ -107,7 +145,7 @@ int proxy_request_header(http_req *req, int enc, client_ctx_t *ctx) { const char *xfp = http_get_header_field(&req->hdr, "X-Forwarded-Proto"); if (xfp == NULL) { if (forwarded == NULL) { - http_add_header_field(&req->hdr, "X-Forwarded-Proto", enc ? "https" : "http"); + http_add_header_field(&req->hdr, "X-Forwarded-Proto", sock->enc ? "https" : "http"); } else { char *ptr = strchr(forwarded, ','); unsigned long len; @@ -180,36 +218,41 @@ int proxy_response_header(http_req *req, http_res *res, host_config_t *conf) { return 0; } -int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t *conf, sock *client, client_ctx_t *cctx, http_status *custom_status, char *err_msg) { +proxy_ctx_t *proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t *conf, sock *client, http_status *custom_status, char *err_msg) { char buffer[CHUNK_SIZE]; const char *connection, *upgrade, *ws_version; long ret; int tries = 0, retry = 0; + struct timeval server_timeout = {.tv_sec = SERVER_TIMEOUT, .tv_usec = 0}; - if (proxy.socket != 0 && strcmp(proxy_host, conf->name) == 0 && sock_check(&proxy) == 0) + proxy_ctx_t *proxy = proxy_get_by_conf(conf); + proxy->in_use = 1; + + if (proxy->initialized && sock_check(&proxy->proxy) == 0) goto proxy; retry: - if (proxy.socket != 0) { + if (proxy->initialized) { info(BLUE_STR "Closing proxy connection"); - sock_close(&proxy); + sock_close(&proxy->proxy); + proxy->initialized = 0; } retry = 0; tries++; - proxy.socket = socket(AF_INET6, SOCK_STREAM, 0); - if (proxy.socket < 0) { + proxy->proxy.socket = socket(AF_INET6, SOCK_STREAM, 0); + if (proxy->proxy.socket < 0) { error("Unable to create socket"); res->status = http_get_status(500); ctx->origin = INTERNAL; - return -1; + return NULL; } server_timeout.tv_sec = SERVER_TIMEOUT_INIT; server_timeout.tv_usec = 0; - if (setsockopt(proxy.socket, SOL_SOCKET, SO_RCVTIMEO, &server_timeout, sizeof(server_timeout)) < 0) + if (setsockopt(proxy->proxy.socket, SOL_SOCKET, SO_RCVTIMEO, &server_timeout, sizeof(server_timeout)) < 0) goto proxy_timeout_err; - if (setsockopt(proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) + if (setsockopt(proxy->proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) goto proxy_timeout_err; struct hostent *host_ent = gethostbyname2(conf->proxy.hostname, AF_INET6); @@ -236,7 +279,7 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t inet_ntop(address.sin6_family, (void *) &address.sin6_addr, buffer, sizeof(buffer)); info(BLUE_STR "Connecting to " BLD_STR "[%s]:%i" CLR_STR BLUE_STR "...", buffer, conf->proxy.port); - if (connect(proxy.socket, (struct sockaddr *) &address, sizeof(address)) < 0) { + if (connect(proxy->proxy.socket, (struct sockaddr *) &address, sizeof(address)) < 0) { if (errno == ETIMEDOUT || errno == EINPROGRESS) { res->status = http_get_status(504); ctx->origin = SERVER_REQ; @@ -254,9 +297,9 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t server_timeout.tv_sec = SERVER_TIMEOUT; server_timeout.tv_usec = 0; - if (setsockopt(proxy.socket, SOL_SOCKET, SO_RCVTIMEO, &server_timeout, sizeof(server_timeout)) < 0) + if (setsockopt(proxy->proxy.socket, SOL_SOCKET, SO_RCVTIMEO, &server_timeout, sizeof(server_timeout)) < 0) goto proxy_timeout_err; - if (setsockopt(proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) { + if (setsockopt(proxy->proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) { proxy_timeout_err: res->status = http_get_status(500); ctx->origin = INTERNAL; @@ -266,25 +309,26 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t } if (conf->proxy.enc) { - proxy.ssl = SSL_new(proxy.ctx); - SSL_set_fd(proxy.ssl, proxy.socket); - SSL_set_connect_state(proxy.ssl); + proxy->proxy.ssl = SSL_new(proxy_ctx); + SSL_set_fd(proxy->proxy.ssl, proxy->proxy.socket); + SSL_set_connect_state(proxy->proxy.ssl); - ret = SSL_do_handshake(proxy.ssl); - proxy._last_ret = ret; - proxy._errno = errno; - proxy._ssl_error = ERR_get_error(); - proxy.enc = 1; + ret = SSL_do_handshake(proxy->proxy.ssl); + proxy->proxy._last_ret = ret; + proxy->proxy._errno = errno; + proxy->proxy._ssl_error = ERR_get_error(); + proxy->proxy.enc = 1; if (ret < 0) { res->status = http_get_status(502); ctx->origin = SERVER_REQ; - error("Unable to perform handshake: %s", sock_strerror(&proxy)); - sprintf(err_msg, "Unable to perform handshake: %s.", sock_strerror(&proxy)); + error("Unable to perform handshake: %s", sock_strerror(&proxy->proxy)); + sprintf(err_msg, "Unable to perform handshake: %s.", sock_strerror(&proxy->proxy)); goto proxy_err; } } - proxy_host = conf->name; + proxy->initialized = 1; + proxy->host = conf->name; info(BLUE_STR "Established new connection with " BLD_STR "[%s]:%i", buffer, conf->proxy.port); proxy: @@ -297,26 +341,26 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t } else { res->status = http_get_status(501); ctx->origin = INTERNAL; - return -1; + return NULL; } } else { http_remove_header_field(&req->hdr, "Connection", HTTP_REMOVE_ALL); http_add_header_field(&req->hdr, "Connection", "keep-alive"); } - ret = proxy_request_header(req, (int) client->enc, cctx); + ret = proxy_request_header(req, client); if (ret != 0) { res->status = http_get_status(500); ctx->origin = INTERNAL; - return -1; + return NULL; } - ret = http_send_request(&proxy, req); + ret = http_send_request(&proxy->proxy, req); if (ret < 0) { res->status = http_get_status(502); ctx->origin = SERVER_REQ; - error("Unable to send request to server (1): %s", sock_strerror(&proxy)); - sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&proxy)); + error("Unable to send request to server (1): %s", sock_strerror(&proxy->proxy)); + sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&proxy->proxy)); retry = tries < 4; goto proxy_err; } @@ -327,17 +371,17 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t ret = 0; if (content_len > 0) { - ret = sock_splice(&proxy, client, buffer, sizeof(buffer), content_len); + ret = sock_splice(&proxy->proxy, client, buffer, sizeof(buffer), content_len); } else if (transfer_encoding != NULL && strstr(transfer_encoding, "chunked") != NULL) { - ret = sock_splice_chunked(&proxy, client, buffer, sizeof(buffer)); + ret = sock_splice_chunked(&proxy->proxy, client, buffer, sizeof(buffer)); } if (ret < 0 || (content_len != 0 && ret != content_len)) { if (ret == -1) { res->status = http_get_status(502); ctx->origin = SERVER_REQ; - error("Unable to send request to server (2): %s", sock_strerror(&proxy)); - sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&proxy)); + error("Unable to send request to server (2): %s", sock_strerror(&proxy->proxy)); + sprintf(err_msg, "Unable to send request to server: %s.", sock_strerror(&proxy->proxy)); retry = tries < 4; goto proxy_err; } else if (ret == -2) { @@ -345,17 +389,17 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t ctx->origin = CLIENT_REQ; error("Unable to receive request from client: %s", sock_strerror(client)); sprintf(err_msg, "Unable to receive request from client: %s.", sock_strerror(client)); - return -1; + return NULL; } res->status = http_get_status(500); ctx->origin = INTERNAL; error("Unknown Error"); - return -1; + return NULL; } - ret = sock_recv(&proxy, buffer, sizeof(buffer), MSG_PEEK); + ret = sock_recv(&proxy->proxy, buffer, sizeof(buffer), MSG_PEEK); if (ret <= 0) { - int enc_err = sock_enc_error(&proxy); + int enc_err = sock_enc_error(&proxy->proxy); if (errno == EAGAIN || errno == EINPROGRESS || enc_err == SSL_ERROR_WANT_READ || enc_err == SSL_ERROR_WANT_WRITE) { @@ -365,8 +409,8 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t res->status = http_get_status(502); ctx->origin = SERVER_RES; } - error("Unable to receive response from server: %s", sock_strerror(&proxy)); - sprintf(err_msg, "Unable to receive response from server: %s.", sock_strerror(&proxy)); + error("Unable to receive response from server: %s", sock_strerror(&proxy->proxy)); + sprintf(err_msg, "Unable to receive response from server: %s.", sock_strerror(&proxy->proxy)); retry = tries < 4; goto proxy_err; } @@ -440,23 +484,24 @@ int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t } ptr = pos0 + 2; } - sock_recv(&proxy, buffer, header_len, 0); + sock_recv(&proxy->proxy, buffer, header_len, 0); ret = proxy_response_header(req, res, conf); if (ret != 0) { res->status = http_get_status(500); ctx->origin = INTERNAL; - return -1; + return NULL; } - return 0; + return proxy; proxy_err: + errno = 0; if (retry) goto retry; - return -1; + return NULL; } -int proxy_send(sock *client, unsigned long len_to_send, int flags) { +int proxy_send(proxy_ctx_t *proxy, sock *client, unsigned long len_to_send, int flags) { char buffer[CHUNK_SIZE], comp_out[CHUNK_SIZE], buf[256], *ptr; long ret = 0, len, snd_len; int finish_comp = 0; @@ -479,12 +524,12 @@ int proxy_send(sock *client, unsigned long len_to_send, int flags) { do { snd_len = 0; if (flags & PROXY_CHUNKED) { - ret = sock_get_chunk_header(&proxy); + ret = sock_get_chunk_header(&proxy->proxy); if (ret < 0) { if (ret == -1) { error("Unable to receive from server: Malformed chunk header"); } else { - error("Unable to receive from server: %s", sock_strerror(&proxy)); + error("Unable to receive from server: %s", sock_strerror(&proxy->proxy)); } break; } @@ -502,9 +547,9 @@ int proxy_send(sock *client, unsigned long len_to_send, int flags) { } while (snd_len < len_to_send) { unsigned long avail_in, avail_out; - ret = sock_recv(&proxy, buffer, CHUNK_SIZE < (len_to_send - snd_len) ? CHUNK_SIZE : len_to_send - snd_len, 0); + ret = sock_recv(&proxy->proxy, buffer, CHUNK_SIZE < (len_to_send - snd_len) ? CHUNK_SIZE : len_to_send - snd_len, 0); if (ret <= 0) { - error("Unable to receive from server: %s", sock_strerror(&proxy)); + error("Unable to receive from server: %s", sock_strerror(&proxy->proxy)); break; } len = ret; @@ -544,7 +589,7 @@ int proxy_send(sock *client, unsigned long len_to_send, int flags) { if (finish_comp) goto finish; } if (ret <= 0) break; - if (flags & PROXY_CHUNKED) sock_recv(&proxy, buffer, 2, 0); + if (flags & PROXY_CHUNKED) sock_recv(&proxy->proxy, buffer, 2, 0); } while ((flags & PROXY_CHUNKED) && len_to_send > 0); if (ret <= 0) return -1; @@ -560,8 +605,7 @@ int proxy_send(sock *client, unsigned long len_to_send, int flags) { return 0; } -int proxy_dump(char *buf, long len) { - sock_recv(&proxy, buf, len, 0); - sock_close(&proxy); +int proxy_dump(proxy_ctx_t *proxy, char *buf, long len) { + sock_recv(&proxy->proxy, buf, len, 0); return 0; } diff --git a/src/lib/proxy.h b/src/lib/proxy.h index 12f21ec..94caab1 100644 --- a/src/lib/proxy.h +++ b/src/lib/proxy.h @@ -18,22 +18,30 @@ # define SERVER_NAME "reverse proxy" #endif +#define PROXY_ARRAY_SIZE (MAX_PROXY_CNX_PER_HOST * sizeof(proxy_ctx_t)) + #include "http.h" #include "config.h" -#include "../server.h" -extern sock proxy; +typedef struct { + unsigned char initialized:1; + unsigned char in_use:1; + sock proxy; + char *host; +} proxy_ctx_t; int proxy_preload(void); -int proxy_request_header(http_req *req, int enc, client_ctx_t *ctx); +void proxy_unload(void); + +int proxy_request_header(http_req *req, sock *sock); int proxy_response_header(http_req *req, http_res *res, host_config_t *conf); -int proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t *conf, sock *client, client_ctx_t *cctx, http_status *custom_status, char *err_msg); +proxy_ctx_t *proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_config_t *conf, sock *client, http_status *custom_status, char *err_msg); -int proxy_send(sock *client, unsigned long len_to_send, int flags); +int proxy_send(proxy_ctx_t *proxy, sock *client, unsigned long len_to_send, int flags); -int proxy_dump(char *buf, long len); +int proxy_dump(proxy_ctx_t *proxy, char *buf, long len); #endif //SESIMOS_PROXY_H diff --git a/src/lib/sock.h b/src/lib/sock.h index b5b67dc..0898e97 100644 --- a/src/lib/sock.h +++ b/src/lib/sock.h @@ -19,7 +19,8 @@ typedef struct { union { struct sockaddr sock; struct sockaddr_in6 ipv6; - } addr; + } _addr; + char *addr, *s_addr; SSL_CTX *ctx; SSL *ssl; long _last_ret; diff --git a/src/server.c b/src/server.c index ff562b5..f8283b7 100644 --- a/src/server.c +++ b/src/server.c @@ -16,6 +16,7 @@ #include "lib/proxy.h" #include "lib/geoip.h" #include "workers.h" +#include "worker/func.h" #include #include @@ -70,8 +71,8 @@ static void accept_cb(void *arg) { sock *client = &client_ctx->socket; client->ctx = contexts[0]; - socklen_t addr_len = sizeof(client->addr); - int client_fd = accept(fd, &client->addr.sock, &addr_len); + socklen_t addr_len = sizeof(client->_addr); + int client_fd = accept(fd, &client->_addr.sock, &addr_len); if (client_fd < 0) { critical("Unable to accept connection"); return; diff --git a/src/server.h b/src/server.h index d1a2b20..7de181a 100644 --- a/src/server.h +++ b/src/server.h @@ -9,16 +9,7 @@ #ifndef SESIMOS_SERVER_H #define SESIMOS_SERVER_H -#include "lib/sock.h" -#include "lib/http.h" -#include "lib/uri.h" -#include "lib/config.h" -#include "lib/fastcgi.h" - -#include -#include #include -#include #define NUM_SOCKETS 2 #define LISTEN_BACKLOG 16 @@ -31,29 +22,6 @@ #define CNX_HANDLER_WORKERS 8 #define REQ_HANDLER_WORKERS 16 -typedef struct { - sock socket; - int req_num; - char *addr, *s_addr; - unsigned char in_use: 1, s_keep_alive:1, c_keep_alive:1; - char cc[3], host[256]; - char req_host[256], err_msg[256]; - char log_prefix[512]; - char _c_addr[INET6_ADDRSTRLEN + 1], _s_addr[INET6_ADDRSTRLEN + 1]; - struct timespec begin, end; - http_req req; - http_res res; - http_uri uri; - http_status_ctx status; - http_status custom_status; - int use_fastcgi, use_proxy; - host_config_t *conf; - FILE *file; - long content_length; - char msg_buf[8192], msg_content[1024]; -} client_ctx_t; - extern volatile sig_atomic_t server_alive; - #endif //SESIMOS_SERVER_H diff --git a/src/worker/fastcgi_handler.c b/src/worker/fastcgi_handler.c index 5caf220..b530804 100644 --- a/src/worker/fastcgi_handler.c +++ b/src/worker/fastcgi_handler.c @@ -11,6 +11,7 @@ #include "../lib/utils.h" #include "../lib/compress.h" #include "../workers.h" +#include "../lib/fastcgi.h" #include @@ -39,7 +40,7 @@ static int fastcgi_handler_1(client_ctx_t *ctx, fastcgi_cnx_t *fcgi_cnx) { fcgi_cnx->socket = 0; fcgi_cnx->req_id = 0; - fcgi_cnx->r_addr = ctx->addr; + fcgi_cnx->r_addr = ctx->socket.addr; fcgi_cnx->r_host = (ctx->host[0] != 0) ? ctx->host : NULL; char buf[1024]; diff --git a/src/worker/func.h b/src/worker/func.h index ce0607d..a113bd0 100644 --- a/src/worker/func.h +++ b/src/worker/func.h @@ -9,7 +9,38 @@ #ifndef SESIMOS_FUNC_H #define SESIMOS_FUNC_H -#include "../server.h" +#include "../lib/sock.h" +#include "../lib/http.h" +#include "../lib/uri.h" +#include "../lib/config.h" +#include "../lib/proxy.h" + +typedef struct { + sock socket; + int req_num; + unsigned char in_use: 1, s_keep_alive:1, c_keep_alive:1; + char cc[3], host[256]; + char req_host[256], err_msg[256]; + char log_prefix[512]; + char _c_addr[INET6_ADDRSTRLEN + 1], _s_addr[INET6_ADDRSTRLEN + 1]; + struct timespec begin, end; + http_req req; + http_res res; + http_uri uri; + http_status_ctx status; + http_status custom_status; + int use_fastcgi, use_proxy; + host_config_t *conf; + FILE *file; + long content_length; + char msg_buf[8192], msg_content[1024]; + proxy_ctx_t *proxy; +} client_ctx_t; + +typedef struct { + client_ctx_t *client; + sock *s1, *s2, *s, *r; +} ws_ctx_t; void tcp_acceptor_func(client_ctx_t *ctx); @@ -23,7 +54,7 @@ void fastcgi_handler_func(client_ctx_t *ctx); void proxy_handler_func(client_ctx_t *ctx); -void ws_frame_handler_func(client_ctx_t *ctx); +void ws_frame_handler_func(ws_ctx_t *ctx); int respond(client_ctx_t *ctx); diff --git a/src/worker/local_handler.c b/src/worker/local_handler.c index 8c5fe53..13ef1c8 100644 --- a/src/worker/local_handler.c +++ b/src/worker/local_handler.c @@ -44,6 +44,7 @@ static int local_handler(client_ctx_t *ctx) { int accept_if_modified_since = 0; if (strcmp(req->method, "TRACE") == 0) { + // FIXME not working? res->status = http_get_status(200); http_add_header_field(&res->hdr, "Content-Type", "message/http"); diff --git a/src/worker/proxy_handler.c b/src/worker/proxy_handler.c index c9e1ad8..519b5fa 100644 --- a/src/worker/proxy_handler.c +++ b/src/worker/proxy_handler.c @@ -31,11 +31,7 @@ void proxy_handler_func(client_ctx_t *ctx) { static int proxy_handler_1(client_ctx_t *ctx) { http_res *res = &ctx->res; - http_req *req = &ctx->req; - http_uri *uri = &ctx->uri; http_status_ctx *status = &ctx->status; - sock *client = &ctx->socket; - char *err_msg = ctx->err_msg; char buf[1024]; @@ -43,8 +39,8 @@ static int proxy_handler_1(client_ctx_t *ctx) { http_remove_header_field(&res->hdr, "Date", HTTP_REMOVE_ALL); http_remove_header_field(&res->hdr, "Server", HTTP_REMOVE_ALL); - int ret = proxy_init(req, res, status, ctx->conf, client, ctx, &ctx->custom_status, err_msg); - ctx->use_proxy = (ret == 0); + ctx->proxy = proxy_init(&ctx->req, res, status, ctx->conf, &ctx->socket, &ctx->custom_status, ctx->err_msg); + ctx->use_proxy = (ctx->proxy != NULL); if (res->status->code == 101) { const char *connection = http_get_header_field(&res->hdr, "Connection"); @@ -77,7 +73,7 @@ static int proxy_handler_1(client_ctx_t *ctx) { status->origin = res->status->code >= 400 ? SERVER : NONE; } ctx->use_proxy = 0; - proxy_dump(ctx->msg_content, content_len); + proxy_dump(ctx->proxy, ctx->msg_content, content_len); } } } @@ -120,7 +116,9 @@ static int proxy_handler_2(client_ctx_t *ctx) { } int flags = (chunked ? PROXY_CHUNKED : 0) | (ctx->use_proxy & PROXY_COMPRESS); - int ret = proxy_send(&ctx->socket, len_to_send, flags); + int ret = proxy_send(ctx->proxy, &ctx->socket, len_to_send, flags); + ctx->proxy->in_use = 0; + ctx->proxy = NULL; if (ret < 0) { ctx->c_keep_alive = 0; diff --git a/src/worker/request_handler.c b/src/worker/request_handler.c index b7a0a01..00aa6c9 100644 --- a/src/worker/request_handler.c +++ b/src/worker/request_handler.c @@ -12,18 +12,17 @@ #include "../lib/mpmc.h" #include "../logger.h" #include "../lib/utils.h" -#include "../lib/proxy.h" #include "../lib/websocket.h" +#include "../server.h" #include #include #include -#include static int request_handler(client_ctx_t *ctx); void request_handler_func(client_ctx_t *ctx) { - logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->s_addr, ctx->log_prefix); + logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->socket.s_addr, ctx->log_prefix); switch (request_handler(ctx)) { case 0: @@ -51,8 +50,15 @@ static int request_handler(client_ctx_t *ctx) { err_msg[0] = 0; + ctx->file = NULL; + ctx->proxy = NULL; ctx->use_fastcgi = 0; ctx->use_proxy = 0; + ctx->proxy = NULL; + ctx->msg_content[0] = 0; + ctx->msg_buf[0] = 0; + ctx->req_host[0] = 0; + ctx->err_msg[0] = 0; http_res *res = &ctx->res; res->status = http_get_status(501); @@ -67,18 +73,19 @@ static int request_handler(client_ctx_t *ctx) { clock_gettime(CLOCK_MONOTONIC, &ctx->begin); - //ret = sock_poll_read(&client, NULL, NULL, 1, NULL, NULL, CLIENT_TIMEOUT * 1000); + // FIXME async poll + ret = sock_poll_read(&client, NULL, NULL, 1, NULL, NULL, CLIENT_TIMEOUT * 1000); http_add_header_field(&res->hdr, "Date", http_get_date(buf0, sizeof(buf0))); http_add_header_field(&res->hdr, "Server", SERVER_STR); - /*if (ret <= 0) { + if (ret <= 0) { if (errno != 0) return 0; ctx->c_keep_alive = 0; res->status = http_get_status(408); return 0; - }*/ - //clock_gettime(CLOCK_MONOTONIC, &begin); + } + clock_gettime(CLOCK_MONOTONIC, &ctx->begin); http_req *req = &ctx->req; ret = http_receive_request(client, req); @@ -110,10 +117,10 @@ static int request_handler(client_ctx_t *ctx) { sprintf(err_msg, "Host header field is too long."); return 0; } else if (host_ptr == NULL || strchr(host_ptr, '/') != NULL) { - if (strchr(ctx->addr, ':') == NULL) { - strcpy(ctx->req_host, ctx->addr); + if (strchr(ctx->socket.addr, ':') == NULL) { + strcpy(ctx->req_host, ctx->socket.addr); } else { - sprintf(ctx->req_host, "[%s]", ctx->addr); + sprintf(ctx->req_host, "[%s]", ctx->socket.addr); } res->status = http_get_status(400); sprintf(err_msg, "The client provided no or an invalid Host header field."); @@ -303,7 +310,7 @@ int respond(client_ctx_t *ctx) { if (ctx->use_proxy == 2) { // WebSocket info("Upgrading connection to WebSocket connection"); - ret = ws_handle_connection(client, &proxy); + ret = ws_handle_connection(client, &ctx->proxy->proxy); if (ret != 0) { ctx->c_keep_alive = 0; close_proxy = 1; @@ -335,7 +342,7 @@ int respond(client_ctx_t *ctx) { } else if (ctx->use_fastcgi) { return 2; } else if (ctx->use_proxy) { - return 3; + return 3; } if (ret < 0) { diff --git a/src/worker/tcp_acceptor.c b/src/worker/tcp_acceptor.c index 4561cf7..4e9d526 100644 --- a/src/worker/tcp_acceptor.c +++ b/src/worker/tcp_acceptor.c @@ -13,6 +13,7 @@ #include "../lib/utils.h" #include "../lib/geoip.h" #include "../workers.h" +#include "../server.h" #include #include @@ -32,27 +33,27 @@ void tcp_acceptor_func(client_ctx_t *ctx) { static int tcp_acceptor(client_ctx_t *ctx) { struct sockaddr_in6 server_addr; - inet_ntop(ctx->socket.addr.ipv6.sin6_family, &ctx->socket.addr.ipv6.sin6_addr, ctx->_c_addr, sizeof(ctx->_c_addr)); + 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; + ctx->socket.addr = ctx->_c_addr + 7; } else { - ctx->addr = ctx->_c_addr; + ctx->socket.addr = ctx->_c_addr; } socklen_t len = sizeof(server_addr); getsockname(ctx->socket.socket, (struct sockaddr *) &server_addr, &len); 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; + ctx->socket.s_addr = ctx->_s_addr + 7; } else { - ctx->s_addr = ctx->_s_addr; + ctx->socket.s_addr = ctx->_s_addr; } sprintf(ctx->log_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); + ntohs(server_addr.sin6_port), CLR_STR, /*color_table[0]*/ "", INET6_ADDRSTRLEN, ctx->socket.addr, + ntohs(ctx->socket._addr.ipv6.sin6_port), CLR_STR); - logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->s_addr, ctx->log_prefix); + logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->socket.s_addr, ctx->log_prefix); int ret; char buf[1024]; @@ -61,7 +62,7 @@ static int tcp_acceptor(client_ctx_t *ctx) { clock_gettime(CLOCK_MONOTONIC, &ctx->begin); if (config.dns_server[0] != 0) { - sprintf(buf, "dig @%s +short +time=1 -x %s", config.dns_server, ctx->addr); + sprintf(buf, "dig @%s +short +time=1 -x %s", config.dns_server, ctx->socket.addr); FILE *dig = popen(buf, "r"); if (dig == NULL) { error("Unable to start dig: %s", strerror(errno)); @@ -85,9 +86,9 @@ static int tcp_acceptor(client_ctx_t *ctx) { } ctx->cc[0] = 0; - geoip_lookup_country(&client->addr.sock, ctx->cc); + geoip_lookup_country(&client->_addr.sock, ctx->cc); - info("Connection accepted from %s %s%s%s[%s]", ctx->addr, ctx->host[0] != 0 ? "(" : "", + info("Connection accepted from %s %s%s%s[%s]", ctx->socket.addr, ctx->host[0] != 0 ? "(" : "", ctx->host[0] != 0 ? ctx->host : "", ctx->host[0] != 0 ? ") " : "", ctx->cc[0] != 0 ? ctx->cc : "N/A"); diff --git a/src/worker/tcp_closer.c b/src/worker/tcp_closer.c index 361620e..4c6d6e0 100644 --- a/src/worker/tcp_closer.c +++ b/src/worker/tcp_closer.c @@ -13,7 +13,7 @@ #include void tcp_closer_func(client_ctx_t *ctx) { - logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->s_addr, ctx->log_prefix); + logger_set_prefix("[%*s]%s", INET6_ADDRSTRLEN, ctx->socket.s_addr, ctx->log_prefix); sock_close(&ctx->socket); diff --git a/src/worker/ws_frame_handler.c b/src/worker/ws_frame_handler.c index cd3a208..0e436bc 100644 --- a/src/worker/ws_frame_handler.c +++ b/src/worker/ws_frame_handler.c @@ -8,12 +8,12 @@ #include "func.h" -static int ws_frame_handler(client_ctx_t *ctx); +static int ws_frame_handler(ws_ctx_t *ctx); -void ws_frame_handler_func(client_ctx_t *ctx) { +void ws_frame_handler_func(ws_ctx_t *ctx) { } -static int ws_frame_handler(client_ctx_t *ctx) { +static int ws_frame_handler(ws_ctx_t *ctx) { return 0; } diff --git a/src/workers.h b/src/workers.h index d0b0f84..3ca4cb5 100644 --- a/src/workers.h +++ b/src/workers.h @@ -9,7 +9,7 @@ #ifndef SESIMOS_WORKERS_H #define SESIMOS_WORKERS_H -#include "server.h" +#include "worker/func.h" int workers_init(void);