diff --git a/src/async.c b/src/async.c index 0880996..9b4ea3c 100644 --- a/src/async.c +++ b/src/async.c @@ -81,10 +81,10 @@ static async_evt_t async_e2a(unsigned int events) { } static int async_add_to_queue(evt_listen_t *evt) { - try_again: - if (sem_wait(&lock) != 0) { + while (sem_wait(&lock) != 0) { if (errno == EINTR) { - goto try_again; + errno = 0; + continue; } else { return -1; } diff --git a/src/cache_handler.c b/src/cache_handler.c index 0e5a699..bec7f45 100644 --- a/src/cache_handler.c +++ b/src/cache_handler.c @@ -53,11 +53,10 @@ static int magic_init(void) { } static void magic_mime_type(const char *restrict filename, char *buf) { - retry: - if (sem_wait(&sem_magic) != 0) { + while (sem_wait(&sem_magic) != 0) { if (errno == EINTR) { errno = 0; - goto retry; + continue; } else { critical("Unable to lock magic semaphore"); return; @@ -84,11 +83,10 @@ static void magic_mime_type(const char *restrict filename, char *buf) { } static void magic_charset(const char *restrict filename, char *buf) { - retry: - if (sem_wait(&sem_magic) != 0) { + while (sem_wait(&sem_magic) != 0) { if (errno == EINTR) { errno = 0; - goto retry; + continue; } else { critical("Unable to lock magic semaphore"); return; @@ -136,10 +134,10 @@ static cache_entry_t *cache_get_entry(cache_t *cache, const char *filename) { static cache_entry_t *cache_get_new_entry(cache_t *cache) { // globally lock cache - retry: - if (sem_wait(&sem_cache) != 0) { + while (sem_wait(&sem_cache) != 0) { if (errno == EINTR) { - goto retry; + errno = 0; + continue; } else { return NULL; } @@ -376,11 +374,10 @@ static void cache_mark_entry_dirty(cache_entry_t *entry) { memset(entry->meta.filename_comp_gz, 0, sizeof(entry->meta.filename_comp_gz)); memset(entry->meta.filename_comp_br, 0, sizeof(entry->meta.filename_comp_br)); - try_again_free: - if (sem_wait(&sem_free) != 0) { + while (sem_wait(&sem_free) != 0) { if (errno == EINTR) { errno = 0; - goto try_again_free; + continue; } else { error("Unable to lock semaphore"); errno = 0; @@ -389,11 +386,10 @@ static void cache_mark_entry_dirty(cache_entry_t *entry) { } // try to lock buffer - try_again_lock: - if (sem_wait(&sem_lock) != 0) { + while (sem_wait(&sem_lock) != 0) { if (errno == EINTR) { errno = 0; - goto try_again_lock; + continue; } else { error("Unable to lock semaphore"); errno = 0; diff --git a/src/lib/http.c b/src/lib/http.c index deef451..1d4192d 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -191,7 +191,8 @@ int http_parse_request(char *buf, http_req *req) { if (req->version[0] == 0) { pos1 = (char *) strchr(ptr, ' ') + 1; - if (pos1 == NULL) goto err_hdr_fmt; + if (pos1 == NULL) + return http_error(HTTP_ERROR_HEADER_MALFORMED); if (pos1 - ptr - 1 >= sizeof(req->method)) return http_error(HTTP_ERROR_HEADER_MALFORMED); @@ -203,10 +204,8 @@ int http_parse_request(char *buf, http_req *req) { snprintf(req->method, sizeof(req->method), "%.*s", (int) (pos1 - ptr - 1), ptr); pos2 = (char *) strchr(pos1, ' ') + 1; - if (pos2 == NULL) { - err_hdr_fmt: + if (pos2 == NULL) return http_error(HTTP_ERROR_HEADER_MALFORMED); - } if (memcmp(pos2, "HTTP/", 5) != 0 || memcmp(pos2 + 8, "\r\n", 2) != 0) return http_error(HTTP_ERROR_INVALID_VERSION); diff --git a/src/lib/mpmc.c b/src/lib/mpmc.c index 80ba088..bf4be09 100644 --- a/src/lib/mpmc.c +++ b/src/lib/mpmc.c @@ -52,22 +52,20 @@ int mpmc_init(mpmc_t *ctx, int n_workers, int buf_size, void (*consumer)(void *o int mpmc_queue(mpmc_t *ctx, void *obj) { // wait for buffer to be emptied - try_again_1: - if (sem_wait(&ctx->free) != 0) { + while (sem_wait(&ctx->free) != 0) { if (errno == EINTR) { errno = 0; - goto try_again_1; + continue; } else { return -1; } } // lock wr field - try_again_2: - if (sem_wait(&ctx->lck_wr) != 0) { + while (sem_wait(&ctx->lck_wr) != 0) { if (errno == EINTR) { errno = 0; - goto try_again_2; + continue; } else { sem_post(&ctx->free); return -1; diff --git a/src/lib/proxy.c b/src/lib/proxy.c index 0f2adbb..fadf6ba 100644 --- a/src/lib/proxy.c +++ b/src/lib/proxy.c @@ -105,19 +105,19 @@ proxy_ctx_t *proxy_get_by_conf(host_config_t *conf) { n++; } - try_again_1: - if (sem_wait(&available[n]) != 0) { + while (sem_wait(&available[n]) != 0) { if (errno == EINTR) { - goto try_again_1; + errno = 0; + continue; } else { return NULL; } } - try_again_2: - if (sem_wait(&lock) != 0) { + while (sem_wait(&lock) != 0) { if (errno == EINTR) { - goto try_again_2; + errno = 0; + continue; } else { sem_post(&available[n]); return NULL; @@ -269,24 +269,28 @@ int proxy_response_header(http_req *req, http_res *res, host_config_t *conf) { const char *location = http_get_header_field(&res->hdr, "Location"); if (location != NULL) { char *hostnames[] = {conf->name, conf->proxy.hostname}; + int found = 0; + for (int i = 0; i < sizeof(hostnames) / sizeof(hostnames[0]); i++) { char *hostname = hostnames[i]; + found = 1; p_len = snprintf(buf1, sizeof(buf1), "http://%s/", hostname); - if (strncmp(location, buf1, p_len) == 0) goto match; + if (strstarts(location, buf1)) break; p_len = snprintf(buf1, sizeof(buf1), "https://%s/", hostname); - if (strncmp(location, buf1, p_len) == 0) goto match; + if (strstarts(location, buf1)) break; p_len = snprintf(buf1, sizeof(buf1), "http://%s:%i/", hostname, conf->proxy.port); - if (strncmp(location, buf1, p_len) == 0) goto match; + if (strstarts(location, buf1)) break; p_len = snprintf(buf1, sizeof(buf1), "https://%s:%i/", hostname, conf->proxy.port); - if (strncmp(location, buf1, p_len) == 0) goto match; + if (strstarts(location, buf1)) break; + + found = 0; } - if (0) { - match: + if (found) { strcpy(buf1, location + p_len - 1); http_remove_header_field(&res->hdr, "Location", HTTP_REMOVE_ALL); http_add_header_field(&res->hdr, "Location", buf1); diff --git a/src/logger.c b/src/logger.c index 8bdffee..904ed86 100644 --- a/src/logger.c +++ b/src/logger.c @@ -102,11 +102,10 @@ void logmsgf(log_lvl_t level, const char *restrict format, ...) { printf("\n"); } else { // wait for free slot in buffer - try_again_free: - if (sem_wait(&sem_buf_free) != 0) { + while (sem_wait(&sem_buf_free) != 0) { if (errno == EINTR) { errno = 0; - goto try_again_free; + continue; } else { err("Unable to lock semaphore"); errno = 0; @@ -117,11 +116,10 @@ void logmsgf(log_lvl_t level, const char *restrict format, ...) { } // try to lock buffer - try_again_buf: - if (sem_wait(&sem_buf) != 0) { + while (sem_wait(&sem_buf) != 0) { if (errno == EINTR) { errno = 0; - goto try_again_buf; + continue; } else { err("Unable to lock semaphore"); errno = 0; diff --git a/src/server.c b/src/server.c index 164876a..35e3060 100644 --- a/src/server.c +++ b/src/server.c @@ -82,10 +82,10 @@ static int ssl_servername_cb(SSL *ssl, int *ad, void *arg) { void server_free_client(client_ctx_t *ctx) { // try to lock clients list - retry: - if (sem_wait(&sem_clients_lock) != 0) { + while (sem_wait(&sem_clients_lock) != 0) { if (errno == EINTR) { - goto retry; + errno = 0; + continue; } else { critical("Unable to lock clients list"); return; @@ -140,10 +140,10 @@ static void accept_cb(void *arg) { client_ctx->cnx_e = -1, client_ctx->req_s = -1, client_ctx->req_e = -1, client_ctx->res_ts = -1; // try to lock clients list - retry: - if (sem_wait(&sem_clients_lock) != 0) { + while (sem_wait(&sem_clients_lock) != 0) { if (errno == EINTR) { - goto retry; + errno = 0; + continue; } else { critical("Unable to lock clients list"); return; diff --git a/src/worker/tcp_acceptor.c b/src/worker/tcp_acceptor.c index 8356b09..305f022 100644 --- a/src/worker/tcp_acceptor.c +++ b/src/worker/tcp_acceptor.c @@ -28,6 +28,32 @@ void tcp_acceptor_func(client_ctx_t *ctx) { } } +static int dig(const char *addr, char *host, size_t host_size) { + char buf[1024]; + FILE *out; + int ret; + + sprintf(buf, "dig @%s +short +time=1 -x %s", config.dns_server, addr); + if ((out = popen(buf, "r")) == NULL) { + error("Unable to start dig: %s"); + return -1; + } + + unsigned long read = fread(buf, 1, sizeof(buf), out); + if ((ret = pclose(out)) != 0) { + error("Dig terminated with exit code %i", ret); + return -1; + } + + char *ptr = memchr(buf, '\n', read); + if (ptr == buf || ptr == NULL) return -1; + + ptr[-1] = 0; + strncpy(host, buf, host_size); + + return 0; +} + static int tcp_acceptor(client_ctx_t *ctx) { struct sockaddr_in6 server_addr; @@ -55,35 +81,12 @@ static int tcp_acceptor(client_ctx_t *ctx) { logger_set_prefix("[%*s]%s", ADDRSTRLEN, ctx->socket.s_addr, ctx->log_prefix); - int ret; - char buf[1024]; sock *client = &ctx->socket; - ctx->cnx_s = clock_micros(); - if (config.dns_server[0] != 0) { - 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"); - goto dig_err; - } - unsigned long read = fread(buf, 1, sizeof(buf), dig); - ret = pclose(dig); - if (ret != 0) { - error("Dig terminated with exit code %i", ret); - goto dig_err; - } - char *ptr = memchr(buf, '\n', read); - if (ptr == buf || ptr == NULL) { - goto dig_err; - } - ptr[-1] = 0; - strncpy(ctx->host, buf, sizeof(ctx->host)); - } else { - dig_err: - ctx->host[0] = 0; - } + ctx->host[0] = 0; + if (config.dns_server[0] != 0) + dig(ctx->socket.addr, ctx->host, sizeof(ctx->host)); ctx->cc[0] = 0; geoip_lookup_country(&client->_addr.sock, ctx->cc); @@ -102,8 +105,8 @@ static int tcp_acceptor(client_ctx_t *ctx) { SSL_set_fd(client->ssl, client->socket); SSL_set_accept_state(client->ssl); - ret = SSL_accept(client->ssl); - if (ret != 1) { + int ret; + if ((ret = SSL_accept(client->ssl)) != 1) { sock_error(client, ret); info("Unable to perform handshake"); return -1;