From 171bca55faef3d30b5473405c7eb58964e6c95e0 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Fri, 12 Nov 2021 15:16:09 +0100 Subject: [PATCH] Fixed reverse proxy timeout --- src/lib/rev_proxy.c | 37 ++++++++++++++++++++++++++----------- src/lib/sock.c | 6 +++++- src/lib/sock.h | 2 ++ src/necronda-server.h | 3 ++- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/lib/rev_proxy.c b/src/lib/rev_proxy.c index 6e84b5f..05dd579 100644 --- a/src/lib/rev_proxy.c +++ b/src/lib/rev_proxy.c @@ -181,18 +181,12 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf return -1; } - server_timeout.tv_sec = SERVER_TIMEOUT; + server_timeout.tv_sec = SERVER_TIMEOUT_INIT; server_timeout.tv_usec = 0; if (setsockopt(rev_proxy.socket, SOL_SOCKET, SO_RCVTIMEO, &server_timeout, sizeof(server_timeout)) < 0) goto rev_proxy_timeout_err; - if (setsockopt(rev_proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) { - rev_proxy_timeout_err: - res->status = http_get_status(500); - ctx->origin = INTERNAL; - print(ERR_STR "Unable to set timeout for socket: %s" CLR_STR, strerror(errno)); - sprintf(err_msg, "Unable to set timeout for socket: %s", strerror(errno)); - goto proxy_err; - } + if (setsockopt(rev_proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) + goto rev_proxy_timeout_err; struct hostent *host_ent = gethostbyname2(conf->rev_proxy.hostname, AF_INET6); if (host_ent == NULL) { @@ -234,6 +228,19 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf goto proxy_err; } + server_timeout.tv_sec = SERVER_TIMEOUT; + server_timeout.tv_usec = 0; + if (setsockopt(rev_proxy.socket, SOL_SOCKET, SO_RCVTIMEO, &server_timeout, sizeof(server_timeout)) < 0) + goto rev_proxy_timeout_err; + if (setsockopt(rev_proxy.socket, SOL_SOCKET, SO_SNDTIMEO, &server_timeout, sizeof(server_timeout)) < 0) { + rev_proxy_timeout_err: + res->status = http_get_status(500); + ctx->origin = INTERNAL; + print(ERR_STR "Unable to set timeout for reverse proxy socket: %s" CLR_STR, strerror(errno)); + sprintf(err_msg, "Unable to set timeout for reverse proxy socket: %s", strerror(errno)); + goto proxy_err; + } + if (conf->rev_proxy.enc) { rev_proxy.ssl = SSL_new(rev_proxy.ctx); SSL_set_fd(rev_proxy.ssl, rev_proxy.socket); @@ -319,8 +326,16 @@ int rev_proxy_init(http_req *req, http_res *res, http_status_ctx *ctx, host_conf ret = sock_recv(&rev_proxy, buffer, sizeof(buffer), MSG_PEEK); if (ret <= 0) { - res->status = http_get_status(502); - ctx->origin = SERVER_RES; + int enc_err = sock_enc_error(&rev_proxy); + if (errno == EAGAIN || errno == EINPROGRESS || enc_err == SSL_ERROR_WANT_READ || + enc_err == SSL_ERROR_WANT_WRITE) + { + res->status = http_get_status(504); + ctx->origin = SERVER_RES; + } else { + res->status = http_get_status(502); + ctx->origin = SERVER_RES; + } print(ERR_STR "Unable to receive response from server: %s" CLR_STR, sock_strerror(&rev_proxy)); sprintf(err_msg, "Unable to receive response from server: %s.", sock_strerror(&rev_proxy)); goto proxy_err; diff --git a/src/lib/sock.c b/src/lib/sock.c index 9ed83ec..9b16e64 100644 --- a/src/lib/sock.c +++ b/src/lib/sock.c @@ -12,6 +12,10 @@ #include #include +int sock_enc_error(sock *s) { + return (int) s->enc ? SSL_get_error(s->ssl, (int) s->_last_ret) : 0; +} + const char *sock_strerror(sock *s) { if (s->_last_ret == 0) { return "closed"; @@ -21,7 +25,7 @@ const char *sock_strerror(sock *s) { } const char *err1 = ERR_reason_error_string(s->_ssl_error); const char *err2 = strerror(errno); - switch (SSL_get_error(s->ssl, (int) s->_last_ret)) { + switch (sock_enc_error(s)) { case SSL_ERROR_NONE: return NULL; case SSL_ERROR_ZERO_RETURN: diff --git a/src/lib/sock.h b/src/lib/sock.h index b87e5f2..d427b47 100644 --- a/src/lib/sock.h +++ b/src/lib/sock.h @@ -23,6 +23,8 @@ typedef struct { unsigned long _ssl_error; } sock; +int sock_enc_error(sock *s); + const char *sock_strerror(sock *s); long sock_send(sock *s, void *buf, unsigned long len, int flags); diff --git a/src/necronda-server.h b/src/necronda-server.h index c1a7faa..fb75b17 100644 --- a/src/necronda-server.h +++ b/src/necronda-server.h @@ -17,7 +17,8 @@ #define LISTEN_BACKLOG 16 #define REQ_PER_CONNECTION 200 #define CLIENT_TIMEOUT 3600 -#define SERVER_TIMEOUT 4 +#define SERVER_TIMEOUT_INIT 4 +#define SERVER_TIMEOUT 3600 #define CHUNK_SIZE 8192