diff options
Diffstat (limited to 'pacredir.c')
-rw-r--r-- | pacredir.c | 171 |
1 files changed, 137 insertions, 34 deletions
@@ -38,9 +38,10 @@ unsigned int count_redirect = 0, count_not_found = 0; /*** write_log ***/ static int write_log(FILE *stream, const char *format, ...) { va_list args; - va_start(args, format); + va_start(args, format); vfprintf(stream, format, args); + va_end(args); fflush(stream); return EXIT_SUCCESS; @@ -136,7 +137,7 @@ static void update_hosts(const uint8_t refcnt) { r = sd_bus_open_system(&bus); if (r < 0) { write_log(stderr, "Failed to open system bus: %s\n", strerror(-r)); - goto finish; + goto fast_finish; } r = sd_bus_call_method(bus, "org.freedesktop.resolve1", "/org/freedesktop/resolve1", @@ -157,7 +158,7 @@ static void update_hosts(const uint8_t refcnt) { if (refcnt == 0) { usleep(250000); update_hosts(refcnt + 1); - goto finish; + goto fast_finish; } r = sd_bus_message_enter_container(reply_record, 'a', "(iqqay)"); @@ -337,6 +338,12 @@ finish_service: if (r < 0) goto parse_failure_record; + goto finish; + +parse_failure_record: + write_log(stderr, "Parse failure for record: %s\n", strerror(-r)); + +finish: /* mark hosts offline that did not show up in query */ hosts_ptr = hosts; while (hosts_ptr->host != NULL) { @@ -348,12 +355,7 @@ finish_service: hosts_ptr = hosts_ptr->next; } - goto finish; - -parse_failure_record: - write_log(stderr, "Parse failure for record: %s\n", strerror(-r)); - -finish: +fast_finish: sd_bus_message_unref(reply_record); sd_bus_flush_close_unref(bus); } @@ -382,6 +384,7 @@ static int add_host(const char * host, const uint16_t port, const uint8_t mdns) hosts_ptr->mdns = mdns; hosts_ptr->badtime = 0; hosts_ptr->badcount = 0; + hosts_ptr->finds = 0; hosts_ptr->next = malloc(sizeof(struct hosts)); hosts_ptr->next->host = NULL; @@ -489,6 +492,87 @@ static void * get_http_code(void * data) { return NULL; } +/* append_string */ +static char * append_string(char * string, const char *format, ...) { + va_list args; + size_t string_len = 0, append_len; + + if (string != NULL) + string_len = strlen(string); + + va_start(args, format); + append_len = vsnprintf(NULL, 0, format, args) + 1; + va_end(args); + + string = realloc(string, string_len + append_len); + + va_start(args, format); + vsnprintf(string + string_len, append_len, format, args); + va_end(args); + + return string; +} +/*** status_page ***/ +static char * status_page(void) { + struct ignore_interfaces * ignore_interfaces_ptr = ignore_interfaces; + struct hosts * hosts_ptr = hosts; + char *page = NULL, *overall = CIRCLE_BLUE; + + if (count_redirect + count_not_found) + switch (count_redirect * 4 / (count_redirect + count_not_found)) { + case 0: + overall = CIRCLE_RED; + break; + case 1: + overall = CIRCLE_ORANGE; + break; + case 2: + overall = CIRCLE_YELLOW; + break; + default: + overall = CIRCLE_GREEN; + break; + } + + page = append_string(page, STATUS_HEAD, count_redirect, count_not_found, overall); + + page = append_string(page, STATUS_INT_HEAD); + if (ignore_interfaces_ptr->interface == NULL) + page = append_string(page, STATUS_INT_NONE); + while (ignore_interfaces_ptr->interface != NULL) { + if (ignore_interfaces_ptr->ifindex > 0) + /* write_log(stdout, STATUS_INT_ONE, + ignore_interfaces_ptr->interface, ignore_interfaces_ptr->ifindex); */ + page = append_string(page, STATUS_INT_ONE, + ignore_interfaces_ptr->interface, ignore_interfaces_ptr->ifindex); + else + page = append_string(page, STATUS_INT_ONE_NA, + ignore_interfaces_ptr->interface); + + ignore_interfaces_ptr = ignore_interfaces_ptr->next; + } + page = append_string(page, STATUS_INT_FOOT); + + page = append_string(page, STATUS_HOST_HEAD); + if (hosts_ptr->host == NULL) + page = append_string(page, STATUS_HOST_NONE); + while (hosts_ptr->host != NULL) { + page = append_string(page, STATUS_HOST_ONE, + hosts_ptr->host, hosts_ptr->port, + hosts_ptr->mdns ? (hosts_ptr->online ? CIRCLE_GREEN : CIRCLE_RED) : CIRCLE_BLUE, + hosts_ptr->mdns ? (hosts_ptr->online ? "online" : "offline") : "static", + hosts_ptr->finds ? CIRCLE_GREEN : CIRCLE_BLUE, hosts_ptr->finds, + hosts_ptr->badcount ? CIRCLE_RED : CIRCLE_BLUE, hosts_ptr->badcount); + + hosts_ptr = hosts_ptr->next; + } + page = append_string(page, STATUS_HOST_FOOT); + + page = append_string(page, STATUS_FOOT); + + return page; +} + /*** ahc_echo *** * called whenever a http request is received */ static enum MHD_Result ahc_echo(void * cls, @@ -516,13 +600,33 @@ static enum MHD_Result ahc_echo(void * cls, pthread_t * tid = NULL; struct request ** requests = NULL; struct request * request = NULL; - long http_code = 0; + long http_code = MHD_HTTP_NOT_FOUND; double time_total = INFINITY; char ctime[26]; /* initialize struct timeval */ gettimeofday(&tv, NULL); + /* give status page */ + if (strcmp(uri, "/") == 0) { + http_code = MHD_HTTP_OK; + page = status_page(); + goto response; + } + + /* give favicon */ + if (strcmp(uri, "/favicon.png") == 0) { + http_code = MHD_HTTP_OK; + goto response; + } + + /* give a simple ok response for monitoring */ + if (strcmp(uri, "/check") == 0) { + http_code = MHD_HTTP_OK; + page = strdup("OK"); + goto response; + } + /* we want the filename, not the path */ basename = uri; while (strstr(basename, "/") != NULL) @@ -546,15 +650,6 @@ static enum MHD_Result ahc_echo(void * cls, /* clear context pointer */ *ptr = NULL; - /* redirect to website if no file given */ - if (*basename == 0) { - http_code = MHD_HTTP_OK; - /* duplicate string so we can free it later */ - url = strdup(WEBSITE); - host = basename = "project site"; - goto response; - } - /* process db file request (*.db and *.files) */ if ((strlen(basename) > 3 && strcmp(basename + strlen(basename) - 3, ".db") == 0) || (strlen(basename) > 6 && strcmp(basename + strlen(basename) - 6, ".files") == 0)) { @@ -663,11 +758,12 @@ static enum MHD_Result ahc_echo(void * cls, request->time_total < time_total))) || /* for packages try to guess the fastest peer */ (dbfile == 0 && request->time_total < time_total))) { + request->host->finds++; if (url != NULL) free(url); url = request->url; host = request->host->host; - http_code = MHD_HTTP_OK; + http_code = MHD_HTTP_TEMPORARY_REDIRECT; last_modified = request->last_modified; time_total = request->time_total; } else @@ -677,22 +773,33 @@ static enum MHD_Result ahc_echo(void * cls, /* increase counters before reponse label, do not count redirects to project page */ - if (http_code == MHD_HTTP_OK) + if (http_code == MHD_HTTP_TEMPORARY_REDIRECT) count_redirect++; else count_not_found++; response: /* give response */ - if (http_code == MHD_HTTP_OK) { + if (http_code == MHD_HTTP_TEMPORARY_REDIRECT) { write_log(stdout, "Redirecting to %s: %s\n", host, url); page = malloc(strlen(PAGE307) + strlen(url) + strlen(basename) + 1); sprintf(page, PAGE307, url, basename); response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE); ret = MHD_add_response_header(response, "Location", url); - ret = MHD_queue_response(connection, MHD_HTTP_TEMPORARY_REDIRECT, response); free(url); - } else { + } else if (http_code == MHD_HTTP_OK) { + if (page != NULL) { + write_log(stdout, "Sending status page.\n"); + response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE); + ret = MHD_add_response_header (response, "Content-Type", "text/html"); + } else { + write_log(stdout, "Sending favicon.\n"); + response = MHD_create_response_from_buffer(sizeof(favicon), favicon, MHD_RESPMEM_PERSISTENT); + ret = MHD_add_response_header(response, "ETag", FAVICON_SHA1); + ret = MHD_add_response_header(response, "Cache-Control", "max-age=86400"); + ret = MHD_add_response_header (response, "Content-Type", "image/png"); + } + } else { /* MHD_HTTP_NOT_FOUND */ if (req_count < 0) write_log(stdout, "Currently no peers are available to check for %s.\n", basename); @@ -706,9 +813,10 @@ response: page = malloc(strlen(PAGE404) + strlen(basename) + 1); sprintf(page, PAGE404, basename); response = MHD_create_response_from_buffer(strlen(page), (void*) page, MHD_RESPMEM_MUST_FREE); - ret = MHD_queue_response(connection, MHD_HTTP_NOT_FOUND, response); } + ret = MHD_add_response_header(response, "Server", PROGNAME " v" VERSION " " ID "/" ARCH); + ret = MHD_queue_response(connection, http_code, response); MHD_destroy_response(response); /* report counts to systemd */ @@ -770,15 +878,10 @@ static void sigusr_callback(int signal) { if (hosts_ptr->host == NULL) write_log(stdout, " (none)\n"); while (hosts_ptr->host != NULL) { - if (hosts_ptr->badcount > 0) - write_log(stdout, " -> %s (%s, %s, port: %d, bad count: %d)\n", - hosts_ptr->host, hosts_ptr->mdns ? "mdns" : "static", - hosts_ptr->online ? "online" : "offline", hosts_ptr->port, - hosts_ptr->badcount); - else - write_log(stdout, " -> %s (%s, %s, port: %d)\n", - hosts_ptr->host, hosts_ptr->mdns ? "mdns" : "static", - hosts_ptr->online ? "online" : "offline", hosts_ptr->port); + write_log(stdout, " -> %s (%s, %s, port: %d, finds: %d, bad: %d)\n", + hosts_ptr->host, hosts_ptr->mdns ? "mdns" : "static", + hosts_ptr->online ? "online" : "offline", hosts_ptr->port, + hosts_ptr->finds, hosts_ptr->badcount); hosts_ptr = hosts_ptr->next; } |