aboutsummaryrefslogtreecommitdiffstats
path: root/pacredir.c
diff options
context:
space:
mode:
Diffstat (limited to 'pacredir.c')
-rw-r--r--pacredir.c171
1 files changed, 137 insertions, 34 deletions
diff --git a/pacredir.c b/pacredir.c
index cf9db07..eab868c 100644
--- a/pacredir.c
+++ b/pacredir.c
@@ -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;
}